@fictjs/runtime 0.0.4 → 0.0.5

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.
package/dist/slim.d.cts CHANGED
@@ -9,12 +9,22 @@ interface SignalAccessor<T> {
9
9
  * Computed accessor - function to get computed value
10
10
  */
11
11
  type ComputedAccessor<T> = () => T;
12
+ /**
13
+ * Effect scope disposer - function to dispose an effect scope
14
+ */
15
+ type EffectScopeDisposer = () => void;
12
16
  /**
13
17
  * Create a reactive signal
14
18
  * @param initialValue - The initial value
15
19
  * @returns A signal accessor function
16
20
  */
17
21
  declare function signal<T>(initialValue: T): SignalAccessor<T>;
22
+ /**
23
+ * Create a reactive effect scope
24
+ * @param fn - The scope function
25
+ * @returns An effect scope disposer function
26
+ */
27
+ declare function effectScope(fn: () => void): EffectScopeDisposer;
18
28
  declare const $state: <T>(value: T) => T;
19
29
  /**
20
30
  * Create a selector signal that efficiently updates only when the selected key matches.
@@ -60,9 +70,6 @@ type Effect = () => void | Cleanup;
60
70
  declare function createEffect(fn: Effect): () => void;
61
71
  declare function createRenderEffect(fn: Effect): () => void;
62
72
 
63
- declare function batch<T>(fn: () => T): T;
64
- declare function untrack<T>(fn: () => T): T;
65
-
66
73
  /**
67
74
  * Fict Reactive DOM Binding System
68
75
  *
@@ -76,6 +83,8 @@ declare function untrack<T>(fn: () => T): T;
76
83
  * - The compiler transforms JSX expressions to use these primitives
77
84
  */
78
85
 
86
+ /** A reactive value that can be either static or a getter function */
87
+ type MaybeReactive<T> = T | (() => T);
79
88
  /** Internal type for createElement function reference */
80
89
  type CreateElementFn = (node: FictNode) => Node;
81
90
  /** Handle returned by conditional/list bindings for cleanup */
@@ -212,6 +221,24 @@ type KeyFn<T> = (item: T, index: number) => string | number;
212
221
  */
213
222
  declare function createList<T>(items: () => T[], renderItem: (item: T, index: number) => FictNode, createElementFn: CreateElementFn, getKey?: KeyFn<T>): BindingHandle;
214
223
 
224
+ interface ReactiveScope {
225
+ run<T>(fn: () => T): T;
226
+ stop(): void;
227
+ }
228
+ /**
229
+ * Create an explicit reactive scope that can contain effects/memos and be stopped manually.
230
+ * The scope registers with the current root for cleanup.
231
+ */
232
+ declare function createScope(): ReactiveScope;
233
+ /**
234
+ * Run a block of reactive code inside a managed scope that follows a boolean flag.
235
+ * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.
236
+ */
237
+ declare function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void;
238
+
239
+ declare function batch<T>(fn: () => T): T;
240
+ declare function untrack<T>(fn: () => T): T;
241
+
215
242
  /**
216
243
  * Fict DOM Rendering System
217
244
  *
@@ -472,4 +499,4 @@ type PropGetter<T> = (() => T) & {
472
499
  */
473
500
  declare function useProp<T>(getter: () => T): PropGetter<T>;
474
501
 
475
- export { $state, Fragment, __fictPopContext, __fictProp, __fictPropsRest, __fictPushContext, __fictRender, __fictResetContext, __fictUseContext, __fictUseEffect, __fictUseMemo, __fictUseSignal, batch, bindAttribute, bindClass, bindEvent, bindProperty, bindRef, bindStyle, bindText, clearDelegatedEvents, createConditional, createEffect, createElement, createKeyedBlock, createKeyedList, createKeyedListContainer, createList, createMemo, createPropsProxy, createRenderEffect, createSelector, signal as createSignal, delegateEvents, destroyMarkerBlock, getFirstNodeAfter, insert, insertNodesBefore, mergeProps, moveMarkerBlock, onDestroy, __fictProp as prop, removeNodes, render, template, toNodeArray, untrack, useProp };
502
+ export { $state, Fragment, type ReactiveScope, __fictPopContext, __fictProp, __fictPropsRest, __fictPushContext, __fictRender, __fictResetContext, __fictUseContext, __fictUseEffect, __fictUseMemo, __fictUseSignal, batch, bindAttribute, bindClass, bindEvent, bindProperty, bindRef, bindStyle, bindText, clearDelegatedEvents, createConditional, createEffect, createElement, createKeyedBlock, createKeyedList, createKeyedListContainer, createList, createMemo, createPropsProxy, createRenderEffect, createScope, createSelector, signal as createSignal, delegateEvents, destroyMarkerBlock, effectScope, getFirstNodeAfter, insert, insertNodesBefore, mergeProps, moveMarkerBlock, onDestroy, __fictProp as prop, removeNodes, render, runInScope, template, toNodeArray, untrack, useProp };
package/dist/slim.d.ts CHANGED
@@ -9,12 +9,22 @@ interface SignalAccessor<T> {
9
9
  * Computed accessor - function to get computed value
10
10
  */
11
11
  type ComputedAccessor<T> = () => T;
12
+ /**
13
+ * Effect scope disposer - function to dispose an effect scope
14
+ */
15
+ type EffectScopeDisposer = () => void;
12
16
  /**
13
17
  * Create a reactive signal
14
18
  * @param initialValue - The initial value
15
19
  * @returns A signal accessor function
16
20
  */
17
21
  declare function signal<T>(initialValue: T): SignalAccessor<T>;
22
+ /**
23
+ * Create a reactive effect scope
24
+ * @param fn - The scope function
25
+ * @returns An effect scope disposer function
26
+ */
27
+ declare function effectScope(fn: () => void): EffectScopeDisposer;
18
28
  declare const $state: <T>(value: T) => T;
19
29
  /**
20
30
  * Create a selector signal that efficiently updates only when the selected key matches.
@@ -60,9 +70,6 @@ type Effect = () => void | Cleanup;
60
70
  declare function createEffect(fn: Effect): () => void;
61
71
  declare function createRenderEffect(fn: Effect): () => void;
62
72
 
63
- declare function batch<T>(fn: () => T): T;
64
- declare function untrack<T>(fn: () => T): T;
65
-
66
73
  /**
67
74
  * Fict Reactive DOM Binding System
68
75
  *
@@ -76,6 +83,8 @@ declare function untrack<T>(fn: () => T): T;
76
83
  * - The compiler transforms JSX expressions to use these primitives
77
84
  */
78
85
 
86
+ /** A reactive value that can be either static or a getter function */
87
+ type MaybeReactive<T> = T | (() => T);
79
88
  /** Internal type for createElement function reference */
80
89
  type CreateElementFn = (node: FictNode) => Node;
81
90
  /** Handle returned by conditional/list bindings for cleanup */
@@ -212,6 +221,24 @@ type KeyFn<T> = (item: T, index: number) => string | number;
212
221
  */
213
222
  declare function createList<T>(items: () => T[], renderItem: (item: T, index: number) => FictNode, createElementFn: CreateElementFn, getKey?: KeyFn<T>): BindingHandle;
214
223
 
224
+ interface ReactiveScope {
225
+ run<T>(fn: () => T): T;
226
+ stop(): void;
227
+ }
228
+ /**
229
+ * Create an explicit reactive scope that can contain effects/memos and be stopped manually.
230
+ * The scope registers with the current root for cleanup.
231
+ */
232
+ declare function createScope(): ReactiveScope;
233
+ /**
234
+ * Run a block of reactive code inside a managed scope that follows a boolean flag.
235
+ * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.
236
+ */
237
+ declare function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void;
238
+
239
+ declare function batch<T>(fn: () => T): T;
240
+ declare function untrack<T>(fn: () => T): T;
241
+
215
242
  /**
216
243
  * Fict DOM Rendering System
217
244
  *
@@ -472,4 +499,4 @@ type PropGetter<T> = (() => T) & {
472
499
  */
473
500
  declare function useProp<T>(getter: () => T): PropGetter<T>;
474
501
 
475
- export { $state, Fragment, __fictPopContext, __fictProp, __fictPropsRest, __fictPushContext, __fictRender, __fictResetContext, __fictUseContext, __fictUseEffect, __fictUseMemo, __fictUseSignal, batch, bindAttribute, bindClass, bindEvent, bindProperty, bindRef, bindStyle, bindText, clearDelegatedEvents, createConditional, createEffect, createElement, createKeyedBlock, createKeyedList, createKeyedListContainer, createList, createMemo, createPropsProxy, createRenderEffect, createSelector, signal as createSignal, delegateEvents, destroyMarkerBlock, getFirstNodeAfter, insert, insertNodesBefore, mergeProps, moveMarkerBlock, onDestroy, __fictProp as prop, removeNodes, render, template, toNodeArray, untrack, useProp };
502
+ export { $state, Fragment, type ReactiveScope, __fictPopContext, __fictProp, __fictPropsRest, __fictPushContext, __fictRender, __fictResetContext, __fictUseContext, __fictUseEffect, __fictUseMemo, __fictUseSignal, batch, bindAttribute, bindClass, bindEvent, bindProperty, bindRef, bindStyle, bindText, clearDelegatedEvents, createConditional, createEffect, createElement, createKeyedBlock, createKeyedList, createKeyedListContainer, createList, createMemo, createPropsProxy, createRenderEffect, createScope, createSelector, signal as createSignal, delegateEvents, destroyMarkerBlock, effectScope, getFirstNodeAfter, insert, insertNodesBefore, mergeProps, moveMarkerBlock, onDestroy, __fictProp as prop, removeNodes, render, runInScope, template, toNodeArray, untrack, useProp };
package/dist/slim.js CHANGED
@@ -99,6 +99,7 @@ function reportCycle(reason, detail = void 0) {
99
99
 
100
100
  // src/lifecycle.ts
101
101
  var currentRoot;
102
+ var currentEffectCleanups;
102
103
  var globalErrorHandlers = /* @__PURE__ */ new WeakMap();
103
104
  var globalSuspenseHandlers = /* @__PURE__ */ new WeakMap();
104
105
  function createRootContext(parent = currentRoot) {
@@ -128,6 +129,9 @@ function onDestroy(fn) {
128
129
  }
129
130
  runLifecycle(fn);
130
131
  }
132
+ function onCleanup(fn) {
133
+ registerEffectCleanup(fn);
134
+ }
131
135
  function flushOnMount(root) {
132
136
  const cbs = root.onMountCallbacks;
133
137
  if (!cbs || cbs.length === 0) return;
@@ -166,10 +170,35 @@ function destroyRoot(root) {
166
170
  globalSuspenseHandlers.delete(root);
167
171
  }
168
172
  }
173
+ function createRoot(fn) {
174
+ const root = createRootContext();
175
+ const prev = pushRoot(root);
176
+ let value;
177
+ try {
178
+ value = fn();
179
+ } finally {
180
+ popRoot(prev);
181
+ }
182
+ flushOnMount(root);
183
+ return {
184
+ dispose: () => destroyRoot(root),
185
+ value
186
+ };
187
+ }
169
188
  function withEffectCleanups(bucket, fn) {
189
+ const prev = currentEffectCleanups;
190
+ currentEffectCleanups = bucket;
170
191
  try {
171
192
  return fn();
172
193
  } finally {
194
+ currentEffectCleanups = prev;
195
+ }
196
+ }
197
+ function registerEffectCleanup(fn) {
198
+ if (currentEffectCleanups) {
199
+ currentEffectCleanups.push(fn);
200
+ } else {
201
+ registerRootCleanup(fn);
173
202
  }
174
203
  }
175
204
  function runCleanupList(list) {
@@ -718,6 +747,21 @@ function effect(fn) {
718
747
  function effectOper() {
719
748
  disposeNode(this);
720
749
  }
750
+ function effectScope(fn) {
751
+ const e = { deps: void 0, depsTail: void 0, subs: void 0, subsTail: void 0, flags: 0 };
752
+ const prevSub = activeSub;
753
+ if (prevSub !== void 0) link(e, prevSub, 0);
754
+ activeSub = e;
755
+ try {
756
+ fn();
757
+ } finally {
758
+ activeSub = prevSub;
759
+ }
760
+ return effectScopeOper.bind(e);
761
+ }
762
+ function effectScopeOper() {
763
+ disposeNode(this);
764
+ }
721
765
  function batch(fn) {
722
766
  ++batchDepth;
723
767
  try {
@@ -861,14 +905,6 @@ function createRenderEffect(fn) {
861
905
  return teardown;
862
906
  }
863
907
 
864
- // src/scheduler.ts
865
- function batch2(fn) {
866
- return batch(fn);
867
- }
868
- function untrack2(fn) {
869
- return untrack(fn);
870
- }
871
-
872
908
  // src/constants.ts
873
909
  var booleans = [
874
910
  "allowfullscreen",
@@ -2345,6 +2381,46 @@ function bumpBlockVersion(block) {
2345
2381
  block.version(block.version() + 1);
2346
2382
  }
2347
2383
 
2384
+ // src/scope.ts
2385
+ function createScope() {
2386
+ let dispose = null;
2387
+ const stop = () => {
2388
+ if (dispose) {
2389
+ dispose();
2390
+ dispose = null;
2391
+ }
2392
+ };
2393
+ const run = (fn) => {
2394
+ stop();
2395
+ const { dispose: rootDispose, value } = createRoot(fn);
2396
+ dispose = rootDispose;
2397
+ return value;
2398
+ };
2399
+ registerRootCleanup(stop);
2400
+ return { run, stop };
2401
+ }
2402
+ function runInScope(flag, fn) {
2403
+ const scope = createScope();
2404
+ const evaluate = () => isReactive(flag) ? flag() : !!flag;
2405
+ createEffect(() => {
2406
+ const enabled = evaluate();
2407
+ if (enabled) {
2408
+ scope.run(fn);
2409
+ } else {
2410
+ scope.stop();
2411
+ }
2412
+ });
2413
+ onCleanup(scope.stop);
2414
+ }
2415
+
2416
+ // src/scheduler.ts
2417
+ function batch2(fn) {
2418
+ return batch(fn);
2419
+ }
2420
+ function untrack2(fn) {
2421
+ return untrack(fn);
2422
+ }
2423
+
2348
2424
  // src/hooks.ts
2349
2425
  var ctxStack = [];
2350
2426
  function __fictUseContext() {
@@ -3333,6 +3409,6 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
3333
3409
  };
3334
3410
  }
3335
3411
 
3336
- export { $state, Fragment, __fictPopContext, __fictProp, __fictPropsRest, __fictPushContext, __fictRender, __fictResetContext, __fictUseContext, __fictUseEffect, __fictUseMemo, __fictUseSignal, batch2 as batch, bindAttribute, bindClass, bindEvent, bindProperty, bindRef, bindStyle, bindText, clearDelegatedEvents, createConditional, createEffect, createElement, createKeyedBlock, createKeyedList, createKeyedListContainer, createList, createMemo, createPropsProxy, createRenderEffect, createSelector, signal as createSignal, delegateEvents, destroyMarkerBlock, getFirstNodeAfter, insert, insertNodesBefore, mergeProps, moveMarkerBlock, onDestroy, __fictProp as prop, removeNodes, render, template, toNodeArray, untrack2 as untrack, useProp };
3412
+ export { $state, Fragment, __fictPopContext, __fictProp, __fictPropsRest, __fictPushContext, __fictRender, __fictResetContext, __fictUseContext, __fictUseEffect, __fictUseMemo, __fictUseSignal, batch2 as batch, bindAttribute, bindClass, bindEvent, bindProperty, bindRef, bindStyle, bindText, clearDelegatedEvents, createConditional, createEffect, createElement, createKeyedBlock, createKeyedList, createKeyedListContainer, createList, createMemo, createPropsProxy, createRenderEffect, createScope, createSelector, signal as createSignal, delegateEvents, destroyMarkerBlock, effectScope, getFirstNodeAfter, insert, insertNodesBefore, mergeProps, moveMarkerBlock, onDestroy, __fictProp as prop, removeNodes, render, runInScope, template, toNodeArray, untrack2 as untrack, useProp };
3337
3413
  //# sourceMappingURL=slim.js.map
3338
3414
  //# sourceMappingURL=slim.js.map