foldkit 0.129.0 → 0.130.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 (84) hide show
  1. package/THIRD-PARTY-NOTICES.md +30 -0
  2. package/dist/brand/brand.d.ts +25 -0
  3. package/dist/brand/brand.d.ts.map +1 -0
  4. package/dist/brand/brand.js +50 -0
  5. package/dist/brand/index.d.ts +2 -0
  6. package/dist/brand/index.d.ts.map +1 -0
  7. package/dist/brand/index.js +1 -0
  8. package/dist/brand/public.d.ts +2 -0
  9. package/dist/brand/public.d.ts.map +1 -0
  10. package/dist/brand/public.js +1 -0
  11. package/dist/canvas/view.d.ts.map +1 -1
  12. package/dist/canvas/view.js +1 -1
  13. package/dist/devTools/protocol.d.ts +1 -1
  14. package/dist/devTools/protocol.d.ts.map +1 -1
  15. package/dist/devTools/protocol.js +1 -1
  16. package/dist/devTools/store.js +2 -2
  17. package/dist/devTools/webSocketBridge.d.ts +1 -1
  18. package/dist/devTools/webSocketBridge.js +1 -1
  19. package/dist/html/index.d.ts +18 -18
  20. package/dist/html/index.d.ts.map +1 -1
  21. package/dist/html/index.js +530 -460
  22. package/dist/html/lazy.d.ts +1 -1
  23. package/dist/html/lazy.d.ts.map +1 -1
  24. package/dist/html/lazy.js +11 -2
  25. package/dist/propsModule.d.ts +1 -1
  26. package/dist/propsModule.d.ts.map +1 -1
  27. package/dist/propsModule.js +6 -1
  28. package/dist/runtime/runtime.d.ts.map +1 -1
  29. package/dist/runtime/runtime.js +468 -278
  30. package/dist/snabbdom/attributes.d.ts +4 -0
  31. package/dist/snabbdom/attributes.d.ts.map +1 -0
  32. package/dist/snabbdom/attributes.js +63 -0
  33. package/dist/snabbdom/class.d.ts +4 -0
  34. package/dist/snabbdom/class.d.ts.map +1 -0
  35. package/dist/snabbdom/class.js +31 -0
  36. package/dist/snabbdom/dataset.d.ts +4 -0
  37. package/dist/snabbdom/dataset.d.ts.map +1 -0
  38. package/dist/snabbdom/dataset.js +42 -0
  39. package/dist/snabbdom/eventlisteners.d.ts +11 -0
  40. package/dist/snabbdom/eventlisteners.d.ts.map +1 -0
  41. package/dist/snabbdom/eventlisteners.js +85 -0
  42. package/dist/snabbdom/h.d.ts +11 -0
  43. package/dist/snabbdom/h.d.ts.map +1 -0
  44. package/dist/snabbdom/h.js +61 -0
  45. package/dist/snabbdom/hooks.d.ts +24 -0
  46. package/dist/snabbdom/hooks.d.ts.map +1 -0
  47. package/dist/snabbdom/hooks.js +1 -0
  48. package/dist/snabbdom/htmldomapi.d.ts +34 -0
  49. package/dist/snabbdom/htmldomapi.d.ts.map +1 -0
  50. package/dist/snabbdom/htmldomapi.js +111 -0
  51. package/dist/snabbdom/index.d.ts +15 -0
  52. package/dist/snabbdom/index.d.ts.map +1 -0
  53. package/dist/snabbdom/index.js +9 -0
  54. package/dist/snabbdom/init.d.ts +14 -0
  55. package/dist/snabbdom/init.d.ts.map +1 -0
  56. package/dist/snabbdom/init.js +486 -0
  57. package/dist/snabbdom/is.d.ts +3 -0
  58. package/dist/snabbdom/is.d.ts.map +1 -0
  59. package/dist/snabbdom/is.js +7 -0
  60. package/dist/snabbdom/module.d.ts +11 -0
  61. package/dist/snabbdom/module.d.ts.map +1 -0
  62. package/dist/snabbdom/module.js +1 -0
  63. package/dist/snabbdom/props.d.ts +2 -0
  64. package/dist/snabbdom/props.d.ts.map +1 -0
  65. package/dist/snabbdom/props.js +1 -0
  66. package/dist/snabbdom/style.d.ts +9 -0
  67. package/dist/snabbdom/style.d.ts.map +1 -0
  68. package/dist/snabbdom/style.js +123 -0
  69. package/dist/snabbdom/tovnode.d.ts +4 -0
  70. package/dist/snabbdom/tovnode.d.ts.map +1 -0
  71. package/dist/snabbdom/tovnode.js +69 -0
  72. package/dist/snabbdom/vnode.d.ts +46 -0
  73. package/dist/snabbdom/vnode.d.ts.map +1 -0
  74. package/dist/snabbdom/vnode.js +13 -0
  75. package/dist/vdom.d.ts +2 -2
  76. package/dist/vdom.d.ts.map +1 -1
  77. package/dist/vdom.js +1 -1
  78. package/package.json +7 -5
  79. package/dist/runtime/messagePriority.d.ts +0 -17
  80. package/dist/runtime/messagePriority.d.ts.map +0 -1
  81. package/dist/runtime/messagePriority.js +0 -33
  82. package/dist/runtime/renderLoop.d.ts +0 -27
  83. package/dist/runtime/renderLoop.d.ts.map +0 -1
  84. package/dist/runtime/renderLoop.js +0 -25
@@ -0,0 +1,69 @@
1
+ /* eslint-disable @typescript-eslint/consistent-type-assertions */
2
+ import { addNS } from './h.js';
3
+ import { htmlDomApi } from './htmldomapi.js';
4
+ import { vnode } from './vnode.js';
5
+ /**
6
+ * Transforms the given attribute name into a valid dataset property key
7
+ * according to https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset#name_conversion
8
+ *
9
+ * @param attributeName data- attribute name, must start with data-
10
+ */
11
+ function datasetKey(attributeName) {
12
+ return attributeName
13
+ .slice(5)
14
+ .replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
15
+ }
16
+ export function toVNode(node, domApi) {
17
+ const api = domApi !== undefined ? domApi : htmlDomApi;
18
+ let text;
19
+ if (api.isElement(node)) {
20
+ const id = node.id ? '#' + node.id : '';
21
+ const cn = node.getAttribute('class')?.match(/[^\t\r\n\f ]+/g);
22
+ const c = cn ? '.' + cn.join('.') : '';
23
+ const sel = api.tagName(node).toLowerCase() + id + c;
24
+ const attrs = {};
25
+ const dataset = {};
26
+ const data = {};
27
+ const children = [];
28
+ let name;
29
+ let i, n;
30
+ const elmAttrs = node.attributes;
31
+ const elmChildren = node.childNodes;
32
+ // NOTE: upstream reads attr.nodeName / attr.nodeValue. Attr.name /
33
+ // Attr.value are identical per the DOM spec, but happy-dom (the repo test
34
+ // environment) returns '' / null for the nodeName / nodeValue aliases, so
35
+ // the spec-equal accessors are used here.
36
+ for (i = 0, n = elmAttrs.length; i < n; i++) {
37
+ name = elmAttrs[i].name;
38
+ if (name.startsWith('data-')) {
39
+ dataset[datasetKey(name)] = elmAttrs[i].value || '';
40
+ }
41
+ else if (name !== 'id' && name !== 'class') {
42
+ attrs[name] = elmAttrs[i].value;
43
+ }
44
+ }
45
+ for (i = 0, n = elmChildren.length; i < n; i++) {
46
+ children.push(toVNode(elmChildren[i], domApi));
47
+ }
48
+ if (Object.keys(attrs).length > 0)
49
+ data.attrs = attrs;
50
+ if (Object.keys(dataset).length > 0)
51
+ data.dataset = dataset;
52
+ if (sel.startsWith('svg') &&
53
+ (sel.length === 3 || sel[3] === '.' || sel[3] === '#')) {
54
+ addNS(data, children, sel);
55
+ }
56
+ return vnode(sel, data, children, undefined, node);
57
+ }
58
+ else if (api.isText(node)) {
59
+ text = api.getTextContent(node);
60
+ return vnode(undefined, undefined, undefined, text, node);
61
+ }
62
+ else if (api.isComment(node)) {
63
+ text = api.getTextContent(node);
64
+ return vnode('!', {}, [], text, node);
65
+ }
66
+ else {
67
+ return vnode('', {}, [], undefined, node);
68
+ }
69
+ }
@@ -0,0 +1,46 @@
1
+ import type { Attrs } from './attributes.js';
2
+ import type { Classes } from './class.js';
3
+ import type { Dataset } from './dataset.js';
4
+ import type { On } from './eventlisteners.js';
5
+ import type { Hooks } from './hooks.js';
6
+ import type { Props } from './props.js';
7
+ import type { VNodeStyle } from './style.js';
8
+ export type Key = PropertyKey;
9
+ export declare const vnodeDataMaskKey: unique symbol;
10
+ export declare const VNodeDataMask: {
11
+ Attrs: number;
12
+ Class: number;
13
+ Dataset: number;
14
+ On: number;
15
+ Props: number;
16
+ Style: number;
17
+ };
18
+ export interface VNode {
19
+ sel: string | undefined;
20
+ data: VNodeData | undefined;
21
+ children: Array<VNode | string> | undefined;
22
+ elm: Node | undefined;
23
+ text: string | undefined;
24
+ key: Key | undefined;
25
+ /** Framework-managed identity stamped by `foldkit/brand`. Independent of
26
+ * `key`: it never enters the keyed index, and joins the `sameVnode`
27
+ * compatibility check exactly where `sel` is consulted. A mismatch
28
+ * replaces the node instead of patching it. */
29
+ identity?: string;
30
+ }
31
+ export interface VNodeData<VNodeProps = Props> {
32
+ [vnodeDataMaskKey]?: number;
33
+ props?: VNodeProps;
34
+ attrs?: Attrs;
35
+ class?: Classes;
36
+ style?: VNodeStyle;
37
+ dataset?: Dataset;
38
+ on?: On;
39
+ hook?: Hooks;
40
+ key?: Key;
41
+ ns?: string;
42
+ is?: string;
43
+ [key: string]: any;
44
+ }
45
+ export declare function vnode(sel: string | undefined, data: any | undefined, children: Array<VNode | string> | undefined, text: string | undefined, elm: Element | DocumentFragment | Text | undefined): VNode;
46
+ //# sourceMappingURL=vnode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vnode.d.ts","sourceRoot":"","sources":["../../src/snabbdom/vnode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,MAAM,GAAG,GAAG,WAAW,CAAA;AAE7B,eAAO,MAAM,gBAAgB,eAAoC,CAAA;AAEjE,eAAO,MAAM,aAAa;;;;;;;CAOzB,CAAA;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,IAAI,EAAE,SAAS,GAAG,SAAS,CAAA;IAC3B,QAAQ,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,SAAS,CAAA;IAC3C,GAAG,EAAE,IAAI,GAAG,SAAS,CAAA;IACrB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,GAAG,EAAE,GAAG,GAAG,SAAS,CAAA;IACpB;;;oDAGgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS,CAAC,UAAU,GAAG,KAAK;IAC3C,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAA;IAC3B,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,EAAE,CAAC,EAAE,EAAE,CAAA;IACP,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED,wBAAgB,KAAK,CACnB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,IAAI,EAAE,GAAG,GAAG,SAAS,EACrB,QAAQ,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,SAAS,EAC3C,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,GAAG,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,GACjD,KAAK,CAGP"}
@@ -0,0 +1,13 @@
1
+ export const vnodeDataMaskKey = Symbol('foldkit/vnode-data-mask');
2
+ export const VNodeDataMask = {
3
+ Attrs: 1,
4
+ Class: 2,
5
+ Dataset: 4,
6
+ On: 8,
7
+ Props: 16,
8
+ Style: 32,
9
+ };
10
+ export function vnode(sel, data, children, text, elm) {
11
+ const key = data === undefined ? undefined : data.key;
12
+ return { sel, data, children, text, elm, key };
13
+ }
package/dist/vdom.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Option } from 'effect';
2
- import { type VNode, toVNode } from 'snabbdom';
3
- export type { VNode } from 'snabbdom';
2
+ import { type VNode, toVNode } from './snabbdom/index.js';
3
+ export type { VNode } from './snabbdom/index.js';
4
4
  export { toVNode };
5
5
  export declare const patch: (oldVnode: VNode | Element | DocumentFragment, vnode: VNode) => VNode;
6
6
  export declare const memoizedVNodes: WeakSet<VNode>;
@@ -1 +1 @@
1
- {"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAA;AAC1C,OAAO,EACL,KAAK,KAAK,EAQV,OAAO,EACR,MAAM,UAAU,CAAA;AAIjB,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,CAAA;AAElB,eAAO,MAAM,KAAK,uEAOhB,CAAA;AAsBF,eAAO,MAAM,cAAc,gBAAuB,CAAA;AA2ClD;;;;mBAImB;AACnB,eAAO,MAAM,kBAAkB,GAC7B,MAAM,KAAK,EACX,OAAM,GAAG,CAAC,MAAM,CAAa,KAC5B,KAA0B,CAAA;AAE7B;;;;;mBAKmB;AACnB,eAAO,MAAM,oBAAoB,GAC/B,MAAM,KAAK,EACX,OAAM,GAAG,CAAC,MAAM,CAAa,KAC5B,KAMF,CAAA;AAED,eAAO,MAAM,YAAY,GACvB,mBAAmB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EACvC,WAAW,KAAK,GAAG,IAAI,EACvB,WAAW,WAAW,EACtB,OAAO,GAAG,CAAC,MAAM,CAAC,KACjB,KASF,CAAA"}
1
+ {"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAA;AAG1C,OAAO,EACL,KAAK,KAAK,EAQV,OAAO,EACR,MAAM,qBAAqB,CAAA;AAE5B,YAAY,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,CAAA;AAElB,eAAO,MAAM,KAAK,uEAOhB,CAAA;AAsBF,eAAO,MAAM,cAAc,gBAAuB,CAAA;AA2ClD;;;;mBAImB;AACnB,eAAO,MAAM,kBAAkB,GAC7B,MAAM,KAAK,EACX,OAAM,GAAG,CAAC,MAAM,CAAa,KAC5B,KAA0B,CAAA;AAE7B;;;;;mBAKmB;AACnB,eAAO,MAAM,oBAAoB,GAC/B,MAAM,KAAK,EACX,OAAM,GAAG,CAAC,MAAM,CAAa,KAC5B,KAMF,CAAA;AAED,eAAO,MAAM,YAAY,GACvB,mBAAmB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EACvC,WAAW,KAAK,GAAG,IAAI,EACvB,WAAW,WAAW,EACtB,OAAO,GAAG,CAAC,MAAM,CAAC,KACjB,KASF,CAAA"}
package/dist/vdom.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Option, Predicate } from 'effect';
2
- import { attributesModule, classModule, datasetModule, eventListenersModule, h, init, styleModule, toVNode, } from 'snabbdom';
3
2
  import { propsModule } from './propsModule.js';
3
+ import { attributesModule, classModule, datasetModule, eventListenersModule, h, init, styleModule, toVNode, } from './snabbdom/index.js';
4
4
  export { toVNode };
5
5
  export const patch = init([
6
6
  attributesModule,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foldkit",
3
- "version": "0.129.0",
3
+ "version": "0.130.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/asyncData/public.d.ts",
16
16
  "import": "./dist/asyncData/public.js"
17
17
  },
18
+ "./brand": {
19
+ "types": "./dist/brand/public.d.ts",
20
+ "import": "./dist/brand/public.js"
21
+ },
18
22
  "./calendar": {
19
23
  "types": "./dist/calendar/public.d.ts",
20
24
  "import": "./dist/calendar/public.js"
@@ -146,7 +150,8 @@
146
150
  },
147
151
  "sideEffects": false,
148
152
  "files": [
149
- "dist"
153
+ "dist",
154
+ "THIRD-PARTY-NOTICES.md"
150
155
  ],
151
156
  "peerDependencies": {
152
157
  "@effect/platform-browser": "4.0.0-beta.97",
@@ -177,9 +182,6 @@
177
182
  "url": "https://github.com/foldkit/foldkit.git",
178
183
  "directory": "packages/foldkit"
179
184
  },
180
- "dependencies": {
181
- "snabbdom": "^3.6.3"
182
- },
183
185
  "publishConfig": {
184
186
  "access": "public"
185
187
  },
@@ -1,17 +0,0 @@
1
- export type Priority = 'High' | 'Normal';
2
- export type EnvelopedMessage<Message> = Readonly<{
3
- priority: Priority;
4
- message: Message;
5
- }>;
6
- /** Reorders a batch of EnvelopedMessages so all `High` envelopes appear
7
- * before any `Normal` envelope, preserving FIFO order within each priority
8
- * class. The runtime calls this on each `Queue.takeAll` batch so user input
9
- * (view dispatch, navigation, subscription events, managed-resource events,
10
- * external dispatchers) lands ahead of chain-derived work (Command results)
11
- * whenever both share a frame.
12
- *
13
- * Single-pass partition: walks the batch once and pushes each unwrapped
14
- * message into either `highs` or `normals`, then concatenates. Avoids the
15
- * four allocations of the previous filter/filter/appendAll/map chain. */
16
- export declare const orderByPriority: <Message>(batch: ReadonlyArray<EnvelopedMessage<Message>>) => ReadonlyArray<Message>;
17
- //# sourceMappingURL=messagePriority.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"messagePriority.d.ts","sourceRoot":"","sources":["../../src/runtime/messagePriority.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC/C,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF;;;;;;;;;0EAS0E;AAC1E,eAAO,MAAM,eAAe,GAAI,OAAO,EACrC,OAAO,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAC9C,aAAa,CAAC,OAAO,CAoBvB,CAAA"}
@@ -1,33 +0,0 @@
1
- import { Array } from 'effect';
2
- /** Reorders a batch of EnvelopedMessages so all `High` envelopes appear
3
- * before any `Normal` envelope, preserving FIFO order within each priority
4
- * class. The runtime calls this on each `Queue.takeAll` batch so user input
5
- * (view dispatch, navigation, subscription events, managed-resource events,
6
- * external dispatchers) lands ahead of chain-derived work (Command results)
7
- * whenever both share a frame.
8
- *
9
- * Single-pass partition: walks the batch once and pushes each unwrapped
10
- * message into either `highs` or `normals`, then concatenates. Avoids the
11
- * four allocations of the previous filter/filter/appendAll/map chain. */
12
- export const orderByPriority = (batch) => {
13
- const highs = [];
14
- const normals = [];
15
- for (const envelope of batch) {
16
- if (envelope.priority === 'High') {
17
- highs.push(envelope.message);
18
- }
19
- else {
20
- normals.push(envelope.message);
21
- }
22
- }
23
- if (Array.isReadonlyArrayEmpty(normals)) {
24
- return highs;
25
- }
26
- if (Array.isReadonlyArrayEmpty(highs)) {
27
- return normals;
28
- }
29
- for (const message of normals) {
30
- highs.push(message);
31
- }
32
- return highs;
33
- };
@@ -1,27 +0,0 @@
1
- import { Effect, SubscriptionRef } from 'effect';
2
- export type RenderLoopConfig = Readonly<{
3
- /** SubscriptionRef holding the dirty bit. The loop subscribes to its changes
4
- * Stream so it can suspend entirely when the bit stays false. */
5
- pendingRef: SubscriptionRef.SubscriptionRef<boolean>;
6
- /** Effect that yields once the next animation frame fires. */
7
- awaitNextFrame: Effect.Effect<void>;
8
- /** Effect that returns whether the runtime is paused (e.g. via DevTools
9
- * time-travel). When true, the body skips render but still clears the bit. */
10
- isPaused: Effect.Effect<boolean>;
11
- /** Effect that performs one render with the latest model. */
12
- render: Effect.Effect<void>;
13
- }>;
14
- /** Builds an idle-suspending render loop driven by a SubscriptionRef of
15
- * "render is pending."
16
- *
17
- * The loop subscribes to the ref's changes Stream and runs the body once per
18
- * false-to-true transition. Stream.changes filters consecutive equals so a
19
- * burst of `set(true)` calls inside one frame produces a single body run.
20
- *
21
- * The body waits for the next animation frame, clears the dirty bit, then
22
- * renders if not paused. The bit is cleared on every body run (including
23
- * paused early-returns) so the next dispatch is always a real false-to-true
24
- * transition. This makes the loop self-recovering even when paused state
25
- * flips externally without a synchronous render. */
26
- export declare const makeRenderLoop: ({ pendingRef, awaitNextFrame, isPaused, render, }: RenderLoopConfig) => Effect.Effect<void>;
27
- //# sourceMappingURL=renderLoop.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderLoop.d.ts","sourceRoot":"","sources":["../../src/runtime/renderLoop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,eAAe,EAAE,MAAM,QAAQ,CAAA;AAExD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC;sEACkE;IAClE,UAAU,EAAE,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IACpD,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACnC;mFAC+E;IAC/E,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAChC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAC5B,CAAC,CAAA;AAEF;;;;;;;;;;;qDAWqD;AACrD,eAAO,MAAM,cAAc,GAAI,mDAK5B,gBAAgB,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAgBvC,CAAA"}
@@ -1,25 +0,0 @@
1
- import { Effect, Stream, SubscriptionRef } from 'effect';
2
- /** Builds an idle-suspending render loop driven by a SubscriptionRef of
3
- * "render is pending."
4
- *
5
- * The loop subscribes to the ref's changes Stream and runs the body once per
6
- * false-to-true transition. Stream.changes filters consecutive equals so a
7
- * burst of `set(true)` calls inside one frame produces a single body run.
8
- *
9
- * The body waits for the next animation frame, clears the dirty bit, then
10
- * renders if not paused. The bit is cleared on every body run (including
11
- * paused early-returns) so the next dispatch is always a real false-to-true
12
- * transition. This makes the loop self-recovering even when paused state
13
- * flips externally without a synchronous render. */
14
- export const makeRenderLoop = ({ pendingRef, awaitNextFrame, isPaused, render, }) => {
15
- const tick = Effect.gen(function* () {
16
- yield* awaitNextFrame;
17
- yield* SubscriptionRef.set(pendingRef, false);
18
- const paused = yield* isPaused;
19
- if (paused) {
20
- return;
21
- }
22
- yield* render;
23
- });
24
- return SubscriptionRef.changes(pendingRef).pipe(Stream.changes, Stream.filter(isPending => isPending), Stream.runForEach(() => tick));
25
- };