Skip to content

serafim-san/kit

 
 

Repository files navigation

san-webkit

Requirements

Following tools should be pre-installed:

  • Node.js >= v20.10.0 – JavaScript runtime environment
  • pnpm = v8.x – package manager

Installation

pnpm is used as a package manager, since it's a more efficient alternative to npm.

Install project's dependencies using a following command:

pnpm i

Publishing a new version of the library

  1. Switch to the next branch and run git pull
  2. Run npm run lib:release

Developing

npm run dev # for HTTP
npm run dev:https # for HTTPS

Chromium-based browsers may require additional steps to access the local HTTPS server:

  • If Accept and Continue button is absent: click anywhere on the page and type thisisunsafe
  • Reset HSTS for the local domain in the chrome://net-internals/#hsts settings

Environment variables

  • process.env.BACKEND_URL - Main backend endpoint
  • process.env.GQL_SERVER_URL - Graphql endpoint that is platform agnostic
  • process.env.NODE_GQL_SERVER_URL - Graphql endpoint that is used only on the server side

Shared Signals coding convention

Signals can be stored in a container to allow them to be passed across function or file boundaries.

There are two types of shared signals:

  • Fixed Shared Signal: { $: T }
  • Deeply Shared Signal: { $$: T }

Fixed Shared Signal

This type of signal uses the $state.raw state declaration, meaning it is not deeply reactive. Reactivity is achieved only by reassigning the container's $ property:

customer.$.name = 'Joe' // This will not trigger updates
customer.$ = customer.$ // Only this will trigger updates
customer.$ = null // This will trigger updates as well

The most common use case for this type of signal is when data has many fields that should be mutated at once, but those fields do not change often.

Deeply Shared Signal

This type of signal uses the $state state declaration, meaning it is deeply reactive. Updates are triggered whenever any of the internal fields change:

currentUser.$$.name = 'Joe' // Triggers update
currentUser.$$.name = 'Mike' // Triggers update
currentUser.$$.email = 'test@gmail.com' // Triggers update

The most common use case for this type of signal is when data has fields that are updated frequently and independently of each other.

How $effect behaves with deeply reactive signals (e.g. currentUser.$$)

We use currentUser from useCustomerCtx and pass it to an update function that accepts selected fields from the user.

Case 1: Passing the full object directly

$effect(() => {
  if (currentUser.$$) {
    update(currentUser.$$)
  }
})

This does not trigger $effect when individual fields of currentUser.$$ change.

Case 2: Copying the object with spread or Object.assign

$effect(() => {
  if (currentUser.$$) {
    update({ ...currentUser.$$ })
  }
})

OR

$effect(() => {
  if (currentUser.$$) {
    const user = Object.assign({}, currentUser.$$)
    update(user)
  }
})

In this case, $effect is triggered when any field of currentUser.$$ changes.

Case 3: Destructuring only required fields

$effect(() => {
  if (currentUser.$$) {
    const { id, name, email } = currentUser.$$
    update({ id, name, email })
  }
})

This triggers $effect only when the selected fields change, which is the expected behavior.

Generics inside Svelte files

The new syntax for defining generics inside generics attribute of the script tag results in the eslint errors.

<script lang="ts" generics="T">
</script>

Therefore to declare a generic type use old meta type $$Generic.

<script lang="ts">
  type T = $$Generic // $$Generic<{ name: string }>
</script>

The order of definitions in Svelte components

<script lang="ts">
  // Define prop types with a separate type definition
  type TProps = { someProp: '' }
  let props: TProps = $props()

  // Initialize and set the external contexts
  const appCtx = useSomeAppCtx.get()
  const someOtherCtx = useSomeOtherCtx.set(props.someProp)

  // Initialize the dialog, which will capture all the contexts defined above
  const showSomeDialog = showSomeDialog$()

  // Define a state signal first
  let state = $state('')
  // Define a derived signal second
  const derived = $derived(state + props.someProp)

  // Create a one-liner using a function expression
  const oneLineFn = () => {}

  onMount(() => {
    // Browser-only code that will run once when the component mounts
    return () => {
      // Cleanup if necessary
    }
  })

  $effect(() => {
    // Browser-only code that re-runs when any tracked signals change
    return () => {
      // Cleanup if necessary
    }
  })

  // Define a function that could be used in the code above
  function someFn() {
    // Function body
  }
</script>

License

This software incorporates several parts of lightweight-charts (https://github.com/tradingview/lightweight-charts, (c) TradingView) that are covered by Apache-2.0 license.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 49.1%
  • Svelte 45.6%
  • JavaScript 3.4%
  • MDX 1.4%
  • CSS 0.5%
  • HTML 0.0%