Skip to main content
On this pageOverview

Init

Overview

The init function returns the initial model and any commands to run on startup. It returns a tuple of [Model, ReadonlyArray<Command<Message>>].

import { Schema as S } from 'effect'
import type { Runtime } from 'foldkit'
import { m } from 'foldkit/message'

const Model = S.Number
type Model = typeof Model.Type

const ClickedIncrement = m('ClickedIncrement')
const ClickedDecrement = m('ClickedDecrement')
const Message = S.Union(ClickedIncrement, ClickedDecrement)
type Message = typeof Message.Type

const init: Runtime.ElementInit<Model, Message> = () => [0, []]

For elements (components without routing), init takes no arguments. For applications with routing, init receives the current URL so you can set up initial state based on the route.

Flags

Flags let you pass initialization data into your application — things like persisted state from localStorage or configuration values. Define a Flags schema and provide an Effect that loads the flags.

import { KeyValueStore } from '@effect/platform'
import { BrowserKeyValueStore } from '@effect/platform-browser'
import { Effect, Option, Schema as S } from 'effect'

const Todo = S.Struct({
  id: S.String,
  text: S.String,
  completed: S.Boolean,
})

const Todos = S.Array(Todo)

const Flags = S.Struct({
  todos: S.Option(Todos),
})

type Flags = typeof Flags.Type

const flags: Effect.Effect<Flags> = Effect.gen(function* () {
  const store = yield* KeyValueStore.KeyValueStore
  const maybeTodosJson = yield* store.get('todos')
  const todosJson = yield* maybeTodosJson

  const decodeTodos = S.decode(S.parseJson(Todos))
  const todos = yield* decodeTodos(todosJson)

  return { todos: Option.some(todos) }
}).pipe(
  Effect.catchAll(() => Effect.succeed({ todos: Option.none() })),
  Effect.provide(BrowserKeyValueStore.layerLocalStorage),
)

When using flags, your init function receives them as the first argument:

import { Option, Schema as S } from 'effect'
import type { Runtime } from 'foldkit'
import { m } from 'foldkit/message'

const Model = S.Struct({
  count: S.Number,
  startingCount: S.Option(S.Number),
})
type Model = typeof Model.Type

const Flags = S.Struct({
  savedCount: S.Option(S.Number),
})
type Flags = typeof Flags.Type

const ClickedIncrement = m('ClickedIncrement')
const Message = S.Union(ClickedIncrement)
type Message = typeof Message.Type

const init: Runtime.ElementInit<Model, Message, Flags> = flags => [
  {
    count: Option.getOrElse(flags.savedCount, () => 0),
    startingCount: flags.savedCount,
  },
  [],
]