foldkit 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/fieldValidation/index.d.ts +3 -4
  2. package/dist/fieldValidation/index.d.ts.map +1 -1
  3. package/dist/fieldValidation/index.js +11 -15
  4. package/dist/html/index.d.ts +42 -0
  5. package/dist/html/index.d.ts.map +1 -1
  6. package/dist/html/index.js +15 -3
  7. package/dist/html/lazy.d.ts +12 -0
  8. package/dist/html/lazy.d.ts.map +1 -0
  9. package/dist/html/lazy.js +35 -0
  10. package/dist/html/public.d.ts +1 -0
  11. package/dist/html/public.d.ts.map +1 -1
  12. package/dist/html/public.js +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -0
  16. package/dist/managedResource/index.d.ts +38 -0
  17. package/dist/managedResource/index.d.ts.map +1 -0
  18. package/dist/managedResource/index.js +20 -0
  19. package/dist/managedResource/public.d.ts +5 -0
  20. package/dist/managedResource/public.d.ts.map +1 -0
  21. package/dist/managedResource/public.js +2 -0
  22. package/dist/runtime/managedResource.d.ts +114 -0
  23. package/dist/runtime/managedResource.d.ts.map +1 -0
  24. package/dist/runtime/managedResource.js +92 -0
  25. package/dist/runtime/public.d.ts +2 -2
  26. package/dist/runtime/public.d.ts.map +1 -1
  27. package/dist/runtime/public.js +1 -1
  28. package/dist/runtime/runtime.d.ts +79 -90
  29. package/dist/runtime/runtime.d.ts.map +1 -1
  30. package/dist/runtime/runtime.js +95 -19
  31. package/dist/runtime/subscription.d.ts +25 -0
  32. package/dist/runtime/subscription.d.ts.map +1 -0
  33. package/dist/runtime/subscription.js +7 -0
  34. package/dist/struct/index.d.ts +2 -0
  35. package/dist/struct/index.d.ts.map +1 -1
  36. package/dist/struct/index.js +4 -0
  37. package/dist/struct/public.d.ts +1 -1
  38. package/dist/struct/public.d.ts.map +1 -1
  39. package/dist/struct/public.js +1 -1
  40. package/dist/subscription/public.d.ts +3 -0
  41. package/dist/subscription/public.d.ts.map +1 -0
  42. package/dist/subscription/public.js +1 -0
  43. package/dist/ui/disclosure/index.d.ts.map +1 -1
  44. package/dist/ui/disclosure/index.js +3 -2
  45. package/dist/ui/listbox/multi.d.ts +172 -0
  46. package/dist/ui/listbox/multi.d.ts.map +1 -0
  47. package/dist/ui/listbox/multi.js +25 -0
  48. package/dist/ui/listbox/multiPublic.d.ts +3 -0
  49. package/dist/ui/listbox/multiPublic.d.ts.map +1 -0
  50. package/dist/ui/listbox/multiPublic.js +1 -0
  51. package/dist/ui/listbox/public.d.ts +5 -2
  52. package/dist/ui/listbox/public.d.ts.map +1 -1
  53. package/dist/ui/listbox/public.js +3 -1
  54. package/dist/ui/listbox/{index.d.ts → shared.d.ts} +77 -23
  55. package/dist/ui/listbox/shared.d.ts.map +1 -0
  56. package/dist/ui/listbox/{index.js → shared.js} +206 -196
  57. package/dist/ui/listbox/single.d.ts +172 -0
  58. package/dist/ui/listbox/single.d.ts.map +1 -0
  59. package/dist/ui/listbox/single.js +29 -0
  60. package/package.json +9 -1
  61. package/dist/ui/listbox/index.d.ts.map +0 -1
@@ -0,0 +1,92 @@
1
+ import { Record } from 'effect';
2
+ /**
3
+ * Creates type-safe managed resource configurations from a dependency schema.
4
+ *
5
+ * Use this when a resource is expensive or stateful and should only exist while
6
+ * the model is in a particular state — a camera stream during a video call, a
7
+ * WebSocket connection while on a chat page, or a Web Worker pool during a
8
+ * computation. For resources that live for the entire application lifetime, use
9
+ * the static `resources` config instead.
10
+ *
11
+ * **Lifecycle** — The runtime watches each config's `modelToMaybeRequirements`
12
+ * after every model update, structurally comparing the result against the
13
+ * previous value:
14
+ *
15
+ * - `Option.none()` → `Option.some(params)`: calls `acquire(params)`, then
16
+ * dispatches `onAcquired(value)`.
17
+ * - `Option.some(paramsA)` → `Option.some(paramsB)` (structurally different):
18
+ * releases the old resource, then acquires a new one with `paramsB`.
19
+ * - `Option.some(params)` → `Option.none()`: calls `release(value)`, then
20
+ * dispatches `onReleased()`. No re-acquisition occurs.
21
+ *
22
+ * If `acquire` fails, `onAcquireError` is dispatched and the resource daemon
23
+ * continues watching for the next deps change — a failed acquisition does not
24
+ * crash the application.
25
+ *
26
+ * **Config fields:**
27
+ *
28
+ * - `resource` — The identity tag created with `ManagedResource.tag`. Appears
29
+ * in the Effect R channel so commands that call `.get` are type-checked.
30
+ * - `modelToMaybeRequirements` — Extracts requirements from the model.
31
+ * `Option.none()` means "release", `Option.some(params)` means
32
+ * "acquire/re-acquire if params changed". For resources with no
33
+ * parameters, use `S.Option(S.Null)` and return `Option.some(null)` —
34
+ * not `S.Struct({})`, which has no fields for equivalence comparison.
35
+ * - `acquire` — Creates the resource from the unwrapped params. The returned
36
+ * Effect should fail when acquisition fails — errors in the error channel
37
+ * flow to `onAcquireError` as a message instead of crashing the runtime.
38
+ * - `release` — Tears down the resource. Errors thrown here are silently
39
+ * swallowed — release must not block cleanup.
40
+ * - `onAcquired` — Message dispatched when `acquire` succeeds.
41
+ * - `onAcquireError` — Message dispatched when `acquire` fails.
42
+ * - `onReleased` — Message dispatched after `release` completes.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const CameraStream = ManagedResource.tag<MediaStream>()('CameraStream')
47
+ *
48
+ * const ManagedResourceDeps = S.Struct({
49
+ * camera: S.Option(S.Struct({ facingMode: S.String })),
50
+ * })
51
+ *
52
+ * const managedResources = ManagedResource.makeManagedResources(
53
+ * ManagedResourceDeps,
54
+ * )<Model, Message>({
55
+ * camera: {
56
+ * resource: CameraStream,
57
+ * modelToMaybeRequirements: model =>
58
+ * pipe(
59
+ * model.callState,
60
+ * Option.liftPredicate(
61
+ * (callState): callState is typeof InCall.Type =>
62
+ * callState._tag === 'InCall',
63
+ * ),
64
+ * Option.map(callState => ({ facingMode: callState.facingMode })),
65
+ * ),
66
+ * acquire: ({ facingMode }) =>
67
+ * Effect.tryPromise(() =>
68
+ * navigator.mediaDevices.getUserMedia({ video: { facingMode } }),
69
+ * ),
70
+ * release: stream =>
71
+ * Effect.sync(() => stream.getTracks().forEach(track => track.stop())),
72
+ * onAcquired: () => AcquiredCamera(),
73
+ * onAcquireError: error => FailedToAcquireCamera({ error: String(error) }),
74
+ * onReleased: () => ReleasedCamera(),
75
+ * },
76
+ * })
77
+ * ```
78
+ *
79
+ * @param ManagedResourceDeps - An Effect Schema struct where each field's type
80
+ * drives the requirements for one managed resource. Wrap in `S.Option(...)` for
81
+ * resources that can be released (most cases).
82
+ *
83
+ * @see {@link ManagedResource.tag} for creating the resource identity.
84
+ */
85
+ export const makeManagedResources = (ManagedResourceDeps) => (configs) =>
86
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
87
+ Record.map(configs, (config, key) =>
88
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
89
+ ({
90
+ schema: ManagedResourceDeps.fields[key],
91
+ ...config,
92
+ }));
@@ -1,5 +1,5 @@
1
- export { makeElement, makeApplication, run, makeSubscriptions } from './runtime';
2
- export type { BrowserConfig, Subscription, Subscriptions, ElementConfigWithFlags, ElementConfigWithoutFlags, ApplicationConfigWithFlags, ApplicationConfigWithoutFlags, ElementInit, ApplicationInit, MakeRuntimeReturn, } from './runtime';
1
+ export { makeElement, makeApplication, run } from './runtime';
2
+ export type { BrowserConfig, ElementConfigWithFlags, ElementConfigWithoutFlags, ApplicationConfigWithFlags, ApplicationConfigWithoutFlags, ElementInit, ApplicationInit, MakeRuntimeReturn, } from './runtime';
3
3
  export { UrlRequest } from './urlRequest';
4
4
  export type { Internal, External } from './urlRequest';
5
5
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/runtime/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEhF,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,6BAA6B,EAC7B,WAAW,EACX,eAAe,EACf,iBAAiB,GAClB,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/runtime/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAE7D,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,6BAA6B,EAC7B,WAAW,EACX,eAAe,EACf,iBAAiB,GAClB,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
@@ -1,2 +1,2 @@
1
- export { makeElement, makeApplication, run, makeSubscriptions } from './runtime';
1
+ export { makeElement, makeApplication, run } from './runtime';
2
2
  export { UrlRequest } from './urlRequest';
@@ -1,7 +1,9 @@
1
- import { Context, Effect, Layer, Schema, Stream } from 'effect';
1
+ import { Context, Effect, Layer, Schema } from 'effect';
2
2
  import type { Command } from '../command';
3
3
  import { Html } from '../html';
4
4
  import { Url } from '../url';
5
+ import type { ManagedResources } from './managedResource';
6
+ import type { Subscriptions } from './subscription';
5
7
  import { UrlRequest } from './urlRequest';
6
8
  declare const Dispatch_base: Context.TagClass<Dispatch, "@foldkit/Dispatch", {
7
9
  readonly dispatchAsync: (message: unknown) => Effect.Effect<void>;
@@ -12,116 +14,103 @@ export declare class Dispatch extends Dispatch_base {
12
14
  }
13
15
  export type { Command } from '../command';
14
16
  /** Configuration for browser URL integration with handlers for URL requests and URL changes. */
15
- export type BrowserConfig<Message> = {
16
- readonly onUrlRequest: (request: UrlRequest) => Message;
17
- readonly onUrlChange: (url: Url) => Message;
18
- };
19
- /** Full runtime configuration including model schema, flags, init, update, view, and optional browser/stream config. */
20
- export interface RuntimeConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never> {
17
+ export type BrowserConfig<Message> = Readonly<{
18
+ onUrlRequest: (request: UrlRequest) => Message;
19
+ onUrlChange: (url: Url) => Message;
20
+ }>;
21
+ type BaseElementConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never, ManagedResourceServices = never> = Readonly<{
21
22
  Model: Schema.Schema<Model, any, never>;
22
- Flags: Schema.Schema<Flags, any, never>;
23
- readonly flags: Effect.Effect<Flags>;
24
- readonly init: (flags: Flags, url?: Url) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
25
- readonly update: (model: Model, message: Message) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
26
- readonly view: (model: Model) => Html;
27
- readonly subscriptions?: Subscriptions<Model, Message, StreamDepsMap, Resources>;
28
- readonly container: HTMLElement;
29
- readonly browser?: BrowserConfig<Message>;
30
- readonly errorView?: (error: Error) => Html;
31
- /**
32
- * An Effect Layer providing long-lived resources that persist across command
33
- * invocations. Use this for browser resources with lifecycle (AudioContext,
34
- * RTCPeerConnection, CanvasRenderingContext2D) — not for stateless utilities
35
- * (HttpClient, JSON encoding) which should be provided per-command.
36
- *
37
- * The runtime memoizes the layer, ensuring a single shared instance for all
38
- * commands and subscriptions throughout the application's lifetime.
39
- */
40
- readonly resources?: Layer.Layer<Resources>;
41
- }
42
- interface BaseElementConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never> {
43
- readonly Model: Schema.Schema<Model, any, never>;
44
- readonly update: (model: Model, message: Message) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
45
- readonly view: (model: Model) => Html;
46
- readonly subscriptions?: Subscriptions<Model, Message, StreamDepsMap, Resources>;
47
- readonly container: HTMLElement;
48
- readonly errorView?: (error: Error) => Html;
49
- readonly resources?: Layer.Layer<Resources>;
50
- }
23
+ update: (model: Model, message: Message) => [
24
+ Model,
25
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
26
+ ];
27
+ view: (model: Model) => Html;
28
+ subscriptions?: Subscriptions<Model, Message, StreamDepsMap, Resources | ManagedResourceServices>;
29
+ container: HTMLElement;
30
+ errorView?: (error: Error) => Html;
31
+ slowViewThresholdMs?: number | false;
32
+ resources?: Layer.Layer<Resources>;
33
+ managedResources?: ManagedResources<Model, Message, ManagedResourceServices>;
34
+ }>;
51
35
  /** Configuration for `makeElement` when the element receives initial data via flags. */
52
- export interface ElementConfigWithFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never> extends BaseElementConfig<Model, Message, StreamDepsMap, Resources> {
53
- readonly Flags: Schema.Schema<Flags, any, never>;
54
- readonly flags: Effect.Effect<Flags>;
55
- readonly init: (flags: Flags) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
56
- }
36
+ export type ElementConfigWithFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never, ManagedResourceServices = never> = BaseElementConfig<Model, Message, StreamDepsMap, Resources, ManagedResourceServices> & Readonly<{
37
+ Flags: Schema.Schema<Flags, any, never>;
38
+ flags: Effect.Effect<Flags>;
39
+ init: (flags: Flags) => [
40
+ Model,
41
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
42
+ ];
43
+ }>;
57
44
  /** Configuration for `makeElement` without flags. */
58
- export interface ElementConfigWithoutFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never> extends BaseElementConfig<Model, Message, StreamDepsMap, Resources> {
59
- readonly init: () => [
45
+ export type ElementConfigWithoutFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never, ManagedResourceServices = never> = BaseElementConfig<Model, Message, StreamDepsMap, Resources, ManagedResourceServices> & Readonly<{
46
+ init: () => [
60
47
  Model,
61
- ReadonlyArray<Command<Message, never, Resources>>
48
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
62
49
  ];
63
- }
64
- interface BaseApplicationConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never> {
65
- readonly Model: Schema.Schema<Model, any, never>;
66
- readonly update: (model: Model, message: Message) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
67
- readonly view: (model: Model) => Html;
68
- readonly subscriptions?: Subscriptions<Model, Message, StreamDepsMap, Resources>;
69
- readonly container: HTMLElement;
70
- readonly browser: BrowserConfig<Message>;
71
- readonly errorView?: (error: Error) => Html;
72
- readonly resources?: Layer.Layer<Resources>;
73
- }
50
+ }>;
51
+ type BaseApplicationConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never, ManagedResourceServices = never> = Readonly<{
52
+ Model: Schema.Schema<Model, any, never>;
53
+ update: (model: Model, message: Message) => [
54
+ Model,
55
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
56
+ ];
57
+ view: (model: Model) => Html;
58
+ subscriptions?: Subscriptions<Model, Message, StreamDepsMap, Resources | ManagedResourceServices>;
59
+ container: HTMLElement;
60
+ browser: BrowserConfig<Message>;
61
+ errorView?: (error: Error) => Html;
62
+ slowViewThresholdMs?: number | false;
63
+ resources?: Layer.Layer<Resources>;
64
+ managedResources?: ManagedResources<Model, Message, ManagedResourceServices>;
65
+ }>;
74
66
  /** Configuration for `makeApplication` when the application receives initial data via flags. */
75
- export interface ApplicationConfigWithFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never> extends BaseApplicationConfig<Model, Message, StreamDepsMap, Resources> {
76
- readonly Flags: Schema.Schema<Flags, any, never>;
77
- readonly flags: Effect.Effect<Flags>;
78
- readonly init: (flags: Flags, url: Url) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
79
- }
67
+ export type ApplicationConfigWithFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never, ManagedResourceServices = never> = BaseApplicationConfig<Model, Message, StreamDepsMap, Resources, ManagedResourceServices> & Readonly<{
68
+ Flags: Schema.Schema<Flags, any, never>;
69
+ flags: Effect.Effect<Flags>;
70
+ init: (flags: Flags, url: Url) => [
71
+ Model,
72
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
73
+ ];
74
+ }>;
80
75
  /** Configuration for `makeApplication` without flags. */
81
- export interface ApplicationConfigWithoutFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never> extends BaseApplicationConfig<Model, Message, StreamDepsMap, Resources> {
82
- readonly init: (url: Url) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
83
- }
76
+ export type ApplicationConfigWithoutFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never, ManagedResourceServices = never> = BaseApplicationConfig<Model, Message, StreamDepsMap, Resources, ManagedResourceServices> & Readonly<{
77
+ init: (url: Url) => [
78
+ Model,
79
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
80
+ ];
81
+ }>;
84
82
  /** The `init` function type for elements, with an optional `flags` parameter when `Flags` is not `void`. */
85
- export type ElementInit<Model, Message, Flags = void, Resources = never> = Flags extends void ? () => [Model, ReadonlyArray<Command<Message, never, Resources>>] : (flags: Flags) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
83
+ export type ElementInit<Model, Message, Flags = void, Resources = never, ManagedResourceServices = never> = Flags extends void ? () => [
84
+ Model,
85
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
86
+ ] : (flags: Flags) => [
87
+ Model,
88
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
89
+ ];
86
90
  /** The `init` function type for applications, receives the current URL and optional flags. */
87
- export type ApplicationInit<Model, Message, Flags = void, Resources = never> = Flags extends void ? (url: Url) => [Model, ReadonlyArray<Command<Message, never, Resources>>] : (flags: Flags, url: Url) => [Model, ReadonlyArray<Command<Message, never, Resources>>];
88
- /** A reactive binding between model state and a long-running stream of commands. */
89
- export type Subscription<Model, Message, StreamDeps, Resources = never> = {
90
- readonly modelToDeps: (model: Model) => StreamDeps;
91
- readonly depsToStream: (deps: StreamDeps) => Stream.Stream<Command<Message, never, Resources>>;
92
- };
93
- type SubscriptionConfig<Model, Message, StreamDeps, Resources = never> = {
94
- readonly schema: Schema.Schema<StreamDeps>;
95
- } & Subscription<Model, Message, StreamDeps, Resources>;
96
- /** A record of named subscription configurations, keyed by dependency field name. */
97
- export type Subscriptions<Model, Message, SubscriptionDeps extends Schema.Struct<any>, Resources = never> = {
98
- readonly [K in keyof Schema.Schema.Type<SubscriptionDeps>]: SubscriptionConfig<Model, Message, Schema.Schema.Type<SubscriptionDeps>[K], Resources>;
99
- };
100
- /** Creates type-safe subscription configurations from a dependency schema. */
101
- export declare const makeSubscriptions: <SubscriptionDeps extends Schema.Struct<any>>(SubscriptionDeps: SubscriptionDeps) => <Model, Message, Resources = never>(configs: { [K in keyof Schema.Schema.Type<SubscriptionDeps>]: {
102
- modelToDeps: (model: Model) => Schema.Schema.Type<SubscriptionDeps>[K];
103
- depsToStream: (deps: Schema.Schema.Type<SubscriptionDeps>[K]) => Stream.Stream<Command<Message, never, Resources>>;
104
- }; }) => Record<string, {
105
- schema: any;
106
- modelToDeps: (model: Model) => Schema.Schema.Type<SubscriptionDeps>[K];
107
- depsToStream: (deps: Schema.Schema.Type<SubscriptionDeps>[K]) => Stream.Stream<Command<Message, never, Resources>>;
108
- }>;
91
+ export type ApplicationInit<Model, Message, Flags = void, Resources = never, ManagedResourceServices = never> = Flags extends void ? (url: Url) => [
92
+ Model,
93
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
94
+ ] : (flags: Flags, url: Url) => [
95
+ Model,
96
+ ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
97
+ ];
109
98
  /** A configured Foldkit runtime returned by `makeElement` or `makeApplication`, passed to `run` to start the application. */
110
99
  export type MakeRuntimeReturn = (hmrModel?: unknown) => Effect.Effect<void>;
111
100
  /** Creates a Foldkit element (no URL routing) and returns a runtime that can be passed to `run`. */
112
101
  export declare function makeElement<Model, Message extends {
113
102
  _tag: string;
114
- }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never>(config: ElementConfigWithFlags<Model, Message, StreamDepsMap, Flags, Resources>): MakeRuntimeReturn;
103
+ }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never, ManagedResourceServices = never>(config: ElementConfigWithFlags<Model, Message, StreamDepsMap, Flags, Resources, ManagedResourceServices>): MakeRuntimeReturn;
115
104
  export declare function makeElement<Model, Message extends {
116
105
  _tag: string;
117
- }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never>(config: ElementConfigWithoutFlags<Model, Message, StreamDepsMap, Resources>): MakeRuntimeReturn;
106
+ }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never, ManagedResourceServices = never>(config: ElementConfigWithoutFlags<Model, Message, StreamDepsMap, Resources, ManagedResourceServices>): MakeRuntimeReturn;
118
107
  /** Creates a Foldkit application with URL routing and returns a runtime that can be passed to `run`. */
119
108
  export declare function makeApplication<Model, Message extends {
120
109
  _tag: string;
121
- }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never>(config: ApplicationConfigWithFlags<Model, Message, StreamDepsMap, Flags, Resources>): MakeRuntimeReturn;
110
+ }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags, Resources = never, ManagedResourceServices = never>(config: ApplicationConfigWithFlags<Model, Message, StreamDepsMap, Flags, Resources, ManagedResourceServices>): MakeRuntimeReturn;
122
111
  export declare function makeApplication<Model, Message extends {
123
112
  _tag: string;
124
- }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never>(config: ApplicationConfigWithoutFlags<Model, Message, StreamDepsMap, Resources>): MakeRuntimeReturn;
113
+ }, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Resources = never, ManagedResourceServices = never>(config: ApplicationConfigWithoutFlags<Model, Message, StreamDepsMap, Resources, ManagedResourceServices>): MakeRuntimeReturn;
125
114
  /** Starts a Foldkit runtime, with HMR support for development. */
126
115
  export declare const run: (foldkitRuntime: MakeRuntimeReturn) => void;
127
116
  //# sourceMappingURL=runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,45 @@
1
1
  import { BrowserRuntime } from '@effect/platform-browser/index';
2
- import { Cause, Context, Effect, Either, Function, Layer, Option, Predicate, Queue, Record, Ref, Runtime, Schema, Stream, SubscriptionRef, pipe, } from 'effect';
2
+ import { Array, Cause, Context, Effect, Either, Function, Layer, Option, Predicate, Queue, Record, Ref, Runtime, Schema, Stream, SubscriptionRef, pipe, } from 'effect';
3
3
  import { h } from 'snabbdom';
4
4
  import { fromString as urlFromString } from '../url';
5
5
  import { patch, toVNode } from '../vdom';
6
6
  import { addBfcacheRestoreListener, addNavigationEventListeners, } from './browserListeners';
7
7
  import { defaultErrorView, noOpDispatch } from './errorUI';
8
+ const SLOW_VIEW_THRESHOLD_MS = 16;
8
9
  /** Effect service tag that provides message dispatching to the view layer. */
9
10
  export class Dispatch extends Context.Tag('@foldkit/Dispatch')() {
10
11
  }
11
- /** Creates type-safe subscription configurations from a dependency schema. */
12
- export const makeSubscriptions = (SubscriptionDeps) => (configs) => Record.map(configs, ({ modelToDeps, depsToStream }, key) => ({
13
- schema: SubscriptionDeps.fields[key],
14
- modelToDeps,
15
- depsToStream,
16
- }));
17
- const makeRuntime = ({ Model, Flags: _Flags, flags: flags_, init, update, view, subscriptions, container, browser: browserConfig, errorView, resources, }) => (hmrModel) => Effect.scoped(Effect.gen(function* () {
12
+ const makeRuntime = ({ Model, Flags: _Flags, flags: flags_, init, update, view, subscriptions, container, browser: browserConfig, errorView, slowViewThresholdMs = SLOW_VIEW_THRESHOLD_MS, resources, managedResources, }) => (hmrModel) => Effect.scoped(Effect.gen(function* () {
18
13
  const maybeResourceLayer = resources
19
14
  ? Option.some(yield* Layer.memoize(resources))
20
15
  : Option.none();
21
- const provideCommandResources = (command) => Option.match(maybeResourceLayer, {
16
+ const managedResourceEntries = managedResources
17
+ ? /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
18
+ Record.toEntries(managedResources)
19
+ : [];
20
+ const managedResourceRefs = yield* Effect.forEach(managedResourceEntries, ([_key, config]) => Ref.make(Option.none()).pipe(Effect.map(ref => ({ config, ref }))));
21
+ const mergeResourceIntoLayer = (layer, { config, ref }) => Layer.merge(layer, Layer.succeed(
22
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
23
+ config.resource._tag, ref));
24
+ const maybeManagedResourceLayer = Array.match(managedResourceRefs, {
25
+ onEmpty: () => Option.none(),
26
+ onNonEmpty: refs => Option.some(Array.reduce(refs,
22
27
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
23
- onNone: () => command,
24
- onSome: resourceLayer => Effect.provide(command, resourceLayer),
28
+ Layer.empty, mergeResourceIntoLayer)),
25
29
  });
30
+ const provideAllResources = (effect) => {
31
+ const withResources = Option.match(maybeResourceLayer, {
32
+ onNone: () => effect,
33
+ onSome: resourceLayer => Effect.provide(effect, resourceLayer),
34
+ });
35
+ return Option.match(maybeManagedResourceLayer, {
36
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
37
+ onNone: () => withResources,
38
+ onSome: managedLayer =>
39
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
40
+ Effect.provide(withResources, managedLayer),
41
+ });
42
+ };
26
43
  const flags = yield* flags_;
27
44
  const modelEquivalence = Schema.equivalence(Model);
28
45
  const messageQueue = yield* Queue.unbounded();
@@ -35,7 +52,7 @@ const makeRuntime = ({ Model, Flags: _Flags, flags: flags_, init, update, view,
35
52
  }))
36
53
  : init(flags, Option.getOrUndefined(currentUrl));
37
54
  const modelSubscriptionRef = yield* SubscriptionRef.make(initModel);
38
- yield* Effect.forEach(initCommands, command => Effect.forkDaemon(command.pipe(provideCommandResources, Effect.flatMap(enqueueMessage))));
55
+ yield* Effect.forEach(initCommands, command => Effect.forkDaemon(command.pipe(provideAllResources, Effect.flatMap(enqueueMessage))));
39
56
  if (browserConfig) {
40
57
  addNavigationEventListeners(messageQueue, browserConfig);
41
58
  }
@@ -51,7 +68,7 @@ const makeRuntime = ({ Model, Flags: _Flags, flags: flags_, init, update, view,
51
68
  yield* SubscriptionRef.set(modelSubscriptionRef, nextModel);
52
69
  preserveModel(nextModel);
53
70
  }
54
- yield* Effect.forEach(commands, command => Effect.forkDaemon(command.pipe(provideCommandResources, Effect.flatMap(enqueueMessage))));
71
+ yield* Effect.forEach(commands, command => Effect.forkDaemon(command.pipe(provideAllResources, Effect.flatMap(enqueueMessage))));
55
72
  });
56
73
  const runProcessMessage = (messageEffect) => (runtime) => {
57
74
  try {
@@ -79,11 +96,19 @@ const makeRuntime = ({ Model, Flags: _Flags, flags: flags_, init, update, view,
79
96
  const dispatchAsync = (message) =>
80
97
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
81
98
  enqueueMessage(message);
82
- const render = (model) => view(model).pipe(Effect.flatMap(nextVNodeNullish => Effect.gen(function* () {
99
+ const render = (model) => Effect.gen(function* () {
100
+ const viewStart = performance.now();
101
+ const nextVNodeNullish = yield* view(model);
102
+ const viewDuration = performance.now() - viewStart;
103
+ if (import.meta.hot &&
104
+ slowViewThresholdMs !== false &&
105
+ viewDuration > slowViewThresholdMs) {
106
+ console.warn(`[foldkit] Slow view: ${viewDuration.toFixed(1)}ms (budget: ${slowViewThresholdMs}ms). Consider moving computation to update or memoizing with createLazy.`);
107
+ }
83
108
  const maybeCurrentVNode = yield* Ref.get(maybeCurrentVNodeRef);
84
109
  const patchedVNode = yield* Effect.sync(() => patchVNode(maybeCurrentVNode, nextVNodeNullish, container));
85
110
  yield* Ref.set(maybeCurrentVNodeRef, Option.some(patchedVNode));
86
- })), Effect.provideService(Dispatch, {
111
+ }).pipe(Effect.provideService(Dispatch, {
87
112
  dispatchAsync,
88
113
  dispatchSync,
89
114
  }));
@@ -92,14 +117,45 @@ const makeRuntime = ({ Model, Flags: _Flags, flags: flags_, init, update, view,
92
117
  yield* render(initModel);
93
118
  addBfcacheRestoreListener();
94
119
  if (subscriptions) {
95
- yield* pipe(subscriptions, Record.toEntries, Effect.forEach(([_key, { schema, modelToDeps, depsToStream }]) => {
120
+ yield* pipe(subscriptions, Record.toEntries, Effect.forEach(([_key, { schema, modelToDependencies, depsToStream }]) => {
96
121
  const modelStream = Stream.concat(Stream.make(initModel), modelSubscriptionRef.changes);
97
- return Effect.forkDaemon(modelStream.pipe(Stream.map(modelToDeps), Stream.changesWith(Schema.equivalence(schema)), Stream.flatMap(depsToStream, { switch: true }), Stream.runForEach(command => command.pipe(provideCommandResources, Effect.flatMap(enqueueMessage)))));
122
+ return Effect.forkDaemon(modelStream.pipe(Stream.map(modelToDependencies), Stream.changesWith(Schema.equivalence(schema)), Stream.flatMap(depsToStream, { switch: true }), Stream.runForEach(command => command.pipe(Effect.flatMap(enqueueMessage))), provideAllResources));
98
123
  }, {
99
124
  concurrency: 'unbounded',
100
125
  discard: true,
101
126
  }));
102
127
  }
128
+ const maybeRequirementsToLifecycle = (config, resourceRef) => (maybeRequirements) => {
129
+ if (Option.isOption(maybeRequirements) &&
130
+ Option.isNone(maybeRequirements)) {
131
+ return Stream.empty;
132
+ }
133
+ const requirements = Option.isOption(maybeRequirements)
134
+ ? Option.getOrThrow(maybeRequirements)
135
+ : maybeRequirements;
136
+ const acquire = Effect.gen(function* () {
137
+ const value = yield* config.acquire(requirements);
138
+ yield* Ref.set(resourceRef, Option.some(value));
139
+ return value;
140
+ });
141
+ const release = (value) => Effect.gen(function* () {
142
+ yield* config.release(value);
143
+ yield* Ref.set(resourceRef, Option.none());
144
+ yield* enqueueMessage(config.onReleased());
145
+ }).pipe(Effect.catchAllCause(() => Effect.void));
146
+ return pipe(Stream.scoped(Effect.acquireRelease(acquire, release)), Stream.flatMap(value => Stream.concat(Stream.make(config.onAcquired(value)), Stream.never)), Stream.map(Effect.succeed), Stream.catchAll(error => Stream.make(Effect.succeed(config.onAcquireError(error)))));
147
+ };
148
+ const forkManagedResourceLifecycle = ({ config, ref: resourceRef, }) => Effect.gen(function* () {
149
+ const modelStream = Stream.concat(Stream.make(initModel), modelSubscriptionRef.changes);
150
+ const equivalence = Schema.equivalence(config.schema);
151
+ yield* Effect.forkDaemon(modelStream.pipe(Stream.map(config.modelToMaybeRequirements), Stream.changesWith(equivalence), Stream.flatMap(maybeRequirementsToLifecycle(config, resourceRef), {
152
+ switch: true,
153
+ }), Stream.runForEach(Effect.flatMap(enqueueMessage))));
154
+ });
155
+ yield* Effect.forEach(managedResourceRefs, forkManagedResourceLifecycle, {
156
+ concurrency: 'unbounded',
157
+ discard: true,
158
+ });
103
159
  yield* pipe(Effect.forever(Effect.gen(function* () {
104
160
  const message = yield* Queue.take(messageQueue);
105
161
  yield* processMessage(message);
@@ -146,17 +202,27 @@ export function makeElement(config) {
146
202
  ...(config.subscriptions && { subscriptions: config.subscriptions }),
147
203
  container: config.container,
148
204
  ...(config.errorView && { errorView: config.errorView }),
205
+ ...(Predicate.isNotUndefined(config.slowViewThresholdMs) && {
206
+ slowViewThresholdMs: config.slowViewThresholdMs,
207
+ }),
149
208
  ...(config.resources && { resources: config.resources }),
209
+ ...(config.managedResources && {
210
+ managedResources: config.managedResources,
211
+ }),
150
212
  };
151
213
  if ('Flags' in config) {
214
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
152
215
  return makeRuntime({
153
216
  ...baseConfig,
154
217
  Flags: config.Flags,
155
218
  flags: config.flags,
156
- init: flags => config.init(flags),
219
+ init: (flags) =>
220
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
221
+ config.init(flags),
157
222
  });
158
223
  }
159
224
  else {
225
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
160
226
  return makeRuntime({
161
227
  ...baseConfig,
162
228
  Flags: Schema.Void,
@@ -175,17 +241,27 @@ export function makeApplication(config) {
175
241
  container: config.container,
176
242
  browser: config.browser,
177
243
  ...(config.errorView && { errorView: config.errorView }),
244
+ ...(Predicate.isNotUndefined(config.slowViewThresholdMs) && {
245
+ slowViewThresholdMs: config.slowViewThresholdMs,
246
+ }),
178
247
  ...(config.resources && { resources: config.resources }),
248
+ ...(config.managedResources && {
249
+ managedResources: config.managedResources,
250
+ }),
179
251
  };
180
252
  if ('Flags' in config) {
253
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
181
254
  return makeRuntime({
182
255
  ...baseConfig,
183
256
  Flags: config.Flags,
184
257
  flags: config.flags,
185
- init: (flags, url) => config.init(flags, url ?? currentUrl),
258
+ init: (flags, url) =>
259
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
260
+ config.init(flags, url ?? currentUrl),
186
261
  });
187
262
  }
188
263
  else {
264
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
189
265
  return makeRuntime({
190
266
  ...baseConfig,
191
267
  Flags: Schema.Void,
@@ -0,0 +1,25 @@
1
+ import { type Schema, type Stream } from 'effect';
2
+ import type { Command } from '../command';
3
+ /** A reactive binding between model state and a long-running stream of commands. */
4
+ export type Subscription<Model, Message, StreamDeps, Resources = never> = {
5
+ readonly modelToDependencies: (model: Model) => StreamDeps;
6
+ readonly depsToStream: (deps: StreamDeps) => Stream.Stream<Command<Message, never, Resources>, never, Resources>;
7
+ };
8
+ type SubscriptionConfig<Model, Message, StreamDeps, Resources = never> = {
9
+ readonly schema: Schema.Schema<StreamDeps>;
10
+ } & Subscription<Model, Message, StreamDeps, Resources>;
11
+ /** A record of named subscription configurations, keyed by dependency field name. */
12
+ export type Subscriptions<Model, Message, SubscriptionDeps extends Schema.Struct<any>, Resources = never> = {
13
+ readonly [K in keyof Schema.Schema.Type<SubscriptionDeps>]: SubscriptionConfig<Model, Message, Schema.Schema.Type<SubscriptionDeps>[K], Resources>;
14
+ };
15
+ /** Creates type-safe subscription configurations from a dependency schema. */
16
+ export declare const makeSubscriptions: <SubscriptionDeps extends Schema.Struct<any>>(SubscriptionDeps: SubscriptionDeps) => <Model, Message, Resources = never>(configs: { [K in keyof Schema.Schema.Type<SubscriptionDeps>]: {
17
+ modelToDependencies: (model: Model) => Schema.Schema.Type<SubscriptionDeps>[K];
18
+ depsToStream: (deps: Schema.Schema.Type<SubscriptionDeps>[K]) => Stream.Stream<Command<Message, never, Resources>, never, Resources>;
19
+ }; }) => Record<string, {
20
+ schema: any;
21
+ modelToDependencies: (model: Model) => Schema.Schema.Type<SubscriptionDeps>[K];
22
+ depsToStream: (deps: Schema.Schema.Type<SubscriptionDeps>[K]) => Stream.Stream<Command<Message, never, Resources>, never, Resources>;
23
+ }>;
24
+ export {};
25
+ //# sourceMappingURL=subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/runtime/subscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,oFAAoF;AACpF,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,GAAG,KAAK,IAAI;IACxE,QAAQ,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,UAAU,CAAA;IAC1D,QAAQ,CAAC,YAAY,EAAE,CACrB,IAAI,EAAE,UAAU,KACb,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAA;CACzE,CAAA;AAED,KAAK,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,GAAG,KAAK,IAAI;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;CAC3C,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;AAEvD,qFAAqF;AACrF,MAAM,MAAM,aAAa,CACvB,KAAK,EACL,OAAO,EACP,gBAAgB,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAC3C,SAAS,GAAG,KAAK,IACf;IACF,QAAQ,EAAE,CAAC,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,kBAAkB,CAC5E,KAAK,EACL,OAAO,EACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EACvC,SAAS,CACV;CACF,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,GAC3B,gBAAgB,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAC1C,kBAAkB,gBAAgB,MAEnC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,GAC1C,CAAC,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG;IACjD,mBAAmB,EAAE,CACnB,KAAK,EAAE,KAAK,KACT,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5C,YAAY,EAAE,CACZ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAC1C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAA;CACzE,GACF;;iCANY,KAAK,KACT,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;yBAEpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAC1C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC;EAOvE,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { Record } from 'effect';
2
+ /** Creates type-safe subscription configurations from a dependency schema. */
3
+ export const makeSubscriptions = (SubscriptionDeps) => (configs) => Record.map(configs, ({ modelToDependencies, depsToStream }, key) => ({
4
+ schema: SubscriptionDeps.fields[key],
5
+ modelToDependencies,
6
+ depsToStream,
7
+ }));
@@ -12,5 +12,7 @@ export declare const evo: {
12
12
  <O, const T extends EvolveTransform<O>>(t: StrictKeys<O, T>): (obj: O) => Evolved<O, T>;
13
13
  <O, const T extends EvolveTransform<O>>(obj: O, t: StrictKeys<O, T>): Evolved<O, T>;
14
14
  };
15
+ /** Creates a variant of `evo` whose transforms are checked against a supertype. Useful in generic contexts where `evo`'s `StrictKeys` can't resolve `keyof` on an open type parameter. The returned function evolves a subtype model, preserving all fields not in the transform, and returns the subtype. */
16
+ export declare const makeConstrainedEvo: <Constraint extends Record<string, unknown>>() => <Model extends Constraint>(model: Model, transforms: EvolveTransform<Constraint>) => Model;
15
17
  export {};
16
18
  //# sourceMappingURL=index.d.ts.map