foldkit 0.90.1 → 0.92.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 (41) hide show
  1. package/README.md +2 -0
  2. package/dist/canvas/index.d.ts +5 -0
  3. package/dist/canvas/index.d.ts.map +1 -0
  4. package/dist/canvas/index.js +2 -0
  5. package/dist/canvas/paint.d.ts +14 -0
  6. package/dist/canvas/paint.d.ts.map +1 -0
  7. package/dist/canvas/paint.js +144 -0
  8. package/dist/canvas/public.d.ts +3 -0
  9. package/dist/canvas/public.d.ts.map +1 -0
  10. package/dist/canvas/public.js +1 -0
  11. package/dist/canvas/shape.d.ts +188 -0
  12. package/dist/canvas/shape.d.ts.map +1 -0
  13. package/dist/canvas/shape.js +103 -0
  14. package/dist/canvas/view.d.ts +38 -0
  15. package/dist/canvas/view.d.ts.map +1 -0
  16. package/dist/canvas/view.js +97 -0
  17. package/dist/devTools/overlay.d.ts +1 -0
  18. package/dist/devTools/overlay.d.ts.map +1 -1
  19. package/dist/devTools/overlay.js +3 -3
  20. package/dist/devTools/store.d.ts +13 -2
  21. package/dist/devTools/store.d.ts.map +1 -1
  22. package/dist/devTools/store.js +24 -9
  23. package/dist/html/index.d.ts +3 -3
  24. package/dist/html/index.d.ts.map +1 -1
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -0
  28. package/dist/runtime/runtime.d.ts +4 -0
  29. package/dist/runtime/runtime.d.ts.map +1 -1
  30. package/dist/runtime/runtime.js +56 -16
  31. package/dist/subscription/animationFrame.d.ts +53 -0
  32. package/dist/subscription/animationFrame.d.ts.map +1 -0
  33. package/dist/subscription/animationFrame.js +47 -0
  34. package/dist/subscription/public.d.ts +2 -0
  35. package/dist/subscription/public.d.ts.map +1 -1
  36. package/dist/subscription/public.js +1 -0
  37. package/dist/ui/dragAndDrop/index.d.ts +1 -1
  38. package/dist/ui/listbox/multi.d.ts +1 -1
  39. package/dist/ui/listbox/shared.d.ts +1 -1
  40. package/dist/ui/listbox/single.d.ts +1 -1
  41. package/package.json +5 -1
@@ -0,0 +1,53 @@
1
+ import { Stream } from 'effect';
2
+ /**
3
+ * Configuration for the `animationFrame` Subscription helper.
4
+ *
5
+ * `isActive(model)` controls whether the request-animation-frame loop is
6
+ * scheduled at all. When it returns `false` (e.g. the game is paused, the
7
+ * scene is static, or the canvas is offscreen), no rAF callbacks fire and
8
+ * no Messages are emitted. The Subscription system automatically restarts
9
+ * the loop when `isActive` flips back to `true`.
10
+ */
11
+ export type AnimationFrameConfig<Model, Message> = Readonly<{
12
+ isActive: (model: Model) => boolean;
13
+ toMessage: (deltaTime: number) => Message;
14
+ }>;
15
+ /**
16
+ * The subscription record returned by `animationFrame`. Shape matches the
17
+ * `{ modelToDependencies, dependenciesToStream }` form expected by
18
+ * `Subscription.makeSubscriptions` field configs.
19
+ */
20
+ export type AnimationFrameSubscription<Model, Message> = Readonly<{
21
+ modelToDependencies: (model: Model) => boolean;
22
+ dependenciesToStream: (isActive: boolean) => Stream.Stream<Message>;
23
+ }>;
24
+ /**
25
+ * Build a Subscription field config that emits a Message on every
26
+ * `requestAnimationFrame` tick, with the inter-frame delta in milliseconds.
27
+ *
28
+ * Pair with `S.Boolean` in the `SubscriptionDeps` schema:
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const SubscriptionDeps = S.Struct({
33
+ * frame: S.Boolean,
34
+ * })
35
+ *
36
+ * const subscriptions = Subscription.makeSubscriptions(SubscriptionDeps)<
37
+ * Model,
38
+ * Message
39
+ * >({
40
+ * frame: Subscription.animationFrame({
41
+ * isActive: model => model.isPlaying,
42
+ * toMessage: deltaTime => Tick({ deltaTime }),
43
+ * }),
44
+ * })
45
+ * ```
46
+ *
47
+ * The browser pauses `requestAnimationFrame` when the tab is hidden, so
48
+ * `deltaTime` may spike on the first frame after the tab regains focus.
49
+ * Clamp it in the update function if your simulation is sensitive to large
50
+ * jumps.
51
+ */
52
+ export declare const animationFrame: <Model, Message>(config: AnimationFrameConfig<Model, Message>) => AnimationFrameSubscription<Model, Message>;
53
+ //# sourceMappingURL=animationFrame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationFrame.d.ts","sourceRoot":"","sources":["../../src/subscription/animationFrame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE9C;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC;IAC1D,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;IACnC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAA;CAC1C,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC;IAChE,mBAAmB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;IAC9C,oBAAoB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;CACpE,CAAC,CAAA;AA2BF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,EAAE,OAAO,EAC3C,QAAQ,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,KAC3C,0BAA0B,CAAC,KAAK,EAAE,OAAO,CAO1C,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { Effect, Queue, Stream } from 'effect';
2
+ const makeAnimationFrameStream = (toMessage) => Stream.callback(queue => Effect.acquireRelease(Effect.sync(() => {
3
+ const state = {
4
+ frameId: 0,
5
+ lastTime: performance.now(),
6
+ };
7
+ const tick = (now) => {
8
+ const deltaTime = now - state.lastTime;
9
+ state.lastTime = now;
10
+ Queue.offerUnsafe(queue, toMessage(deltaTime));
11
+ state.frameId = requestAnimationFrame(tick);
12
+ };
13
+ state.frameId = requestAnimationFrame(tick);
14
+ return state;
15
+ }), state => Effect.sync(() => cancelAnimationFrame(state.frameId))).pipe(Effect.flatMap(() => Effect.never)));
16
+ /**
17
+ * Build a Subscription field config that emits a Message on every
18
+ * `requestAnimationFrame` tick, with the inter-frame delta in milliseconds.
19
+ *
20
+ * Pair with `S.Boolean` in the `SubscriptionDeps` schema:
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const SubscriptionDeps = S.Struct({
25
+ * frame: S.Boolean,
26
+ * })
27
+ *
28
+ * const subscriptions = Subscription.makeSubscriptions(SubscriptionDeps)<
29
+ * Model,
30
+ * Message
31
+ * >({
32
+ * frame: Subscription.animationFrame({
33
+ * isActive: model => model.isPlaying,
34
+ * toMessage: deltaTime => Tick({ deltaTime }),
35
+ * }),
36
+ * })
37
+ * ```
38
+ *
39
+ * The browser pauses `requestAnimationFrame` when the tab is hidden, so
40
+ * `deltaTime` may spike on the first frame after the tab regains focus.
41
+ * Clamp it in the update function if your simulation is sensitive to large
42
+ * jumps.
43
+ */
44
+ export const animationFrame = (config) => ({
45
+ modelToDependencies: model => config.isActive(model),
46
+ dependenciesToStream: isActive => Stream.when(makeAnimationFrameStream(config.toMessage), Effect.sync(() => isActive)),
47
+ });
@@ -1,3 +1,5 @@
1
1
  export { makeSubscriptions } from '../runtime/subscription.js';
2
2
  export type { Subscription, Subscriptions } from '../runtime/subscription.js';
3
+ export { animationFrame } from './animationFrame.js';
4
+ export type { AnimationFrameConfig, AnimationFrameSubscription, } from './animationFrame.js';
3
5
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/subscription/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE9D,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/subscription/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE9D,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAE7E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,YAAY,EACV,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAA"}
@@ -1 +1,2 @@
1
1
  export { makeSubscriptions } from '../runtime/subscription.js';
2
+ export { animationFrame } from './animationFrame.js';
@@ -243,7 +243,7 @@ export declare const subscriptions: import("../../runtime/subscription.js").Subs
243
243
  readonly _tag: "ConfirmedKeyboardDrop";
244
244
  } | {
245
245
  readonly _tag: "PressedArrowKey";
246
- readonly direction: "Up" | "Down" | "Left" | "Right" | "NextContainer" | "PreviousContainer";
246
+ readonly direction: "Left" | "Right" | "Up" | "Down" | "NextContainer" | "PreviousContainer";
247
247
  } | {
248
248
  readonly _tag: "CompletedAutoScroll";
249
249
  } | {
@@ -145,8 +145,8 @@ export declare const update: (model: {
145
145
  readonly _tag: "EndedAnimation";
146
146
  };
147
147
  } | {
148
- readonly button: number;
149
148
  readonly _tag: "PressedPointerOnButton";
149
+ readonly button: number;
150
150
  readonly pointerType: string;
151
151
  }, never, never>;
152
152
  }>[]];
@@ -304,8 +304,8 @@ export declare const makeUpdate: <Model extends BaseModel>(handleSelectedItem: (
304
304
  readonly _tag: "EndedAnimation";
305
305
  };
306
306
  } | {
307
- readonly button: number;
308
307
  readonly _tag: "PressedPointerOnButton";
308
+ readonly button: number;
309
309
  readonly pointerType: string;
310
310
  }, never, never>;
311
311
  }>[]];
@@ -145,8 +145,8 @@ export declare const update: (model: {
145
145
  readonly _tag: "EndedAnimation";
146
146
  };
147
147
  } | {
148
- readonly button: number;
149
148
  readonly _tag: "PressedPointerOnButton";
149
+ readonly button: number;
150
150
  readonly pointerType: string;
151
151
  }, never, never>;
152
152
  }>[]];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foldkit",
3
- "version": "0.90.1",
3
+ "version": "0.92.0",
4
4
  "description": "A TypeScript frontend framework, built on Effect and architected like Elm",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,6 +15,10 @@
15
15
  "types": "./dist/calendar/public.d.ts",
16
16
  "import": "./dist/calendar/public.js"
17
17
  },
18
+ "./canvas": {
19
+ "types": "./dist/canvas/public.d.ts",
20
+ "import": "./dist/canvas/public.js"
21
+ },
18
22
  "./command": {
19
23
  "types": "./dist/command/public.d.ts",
20
24
  "import": "./dist/command/public.js"