@getforma/core 1.4.0 → 1.5.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 (43) hide show
  1. package/dist/{chunk-AJP4OVCN.js → chunk-3U2IQIKB.js} +4 -4
  2. package/dist/{chunk-AJP4OVCN.js.map → chunk-3U2IQIKB.js.map} +1 -1
  3. package/dist/{chunk-FBM7V4NE.cjs → chunk-D46EJ3VS.cjs} +43 -43
  4. package/dist/{chunk-FBM7V4NE.cjs.map → chunk-D46EJ3VS.cjs.map} +1 -1
  5. package/dist/{chunk-Y3A2EVVS.js → chunk-F5QUU76U.js} +4 -4
  6. package/dist/{chunk-Y3A2EVVS.js.map → chunk-F5QUU76U.js.map} +1 -1
  7. package/dist/{chunk-ETPJTPYD.js → chunk-FAIWRZKJ.js} +6 -3
  8. package/dist/chunk-FAIWRZKJ.js.map +1 -0
  9. package/dist/{chunk-H7MDUHS5.cjs → chunk-HAULTMNX.cjs} +6 -2
  10. package/dist/chunk-HAULTMNX.cjs.map +1 -0
  11. package/dist/{chunk-KUXNZ5MG.cjs → chunk-PAKPQRVE.cjs} +14 -12
  12. package/dist/{chunk-KUXNZ5MG.cjs.map → chunk-PAKPQRVE.cjs.map} +1 -1
  13. package/dist/formajs.global.js +69 -11
  14. package/dist/formajs.global.js.map +1 -1
  15. package/dist/http.cjs +11 -11
  16. package/dist/http.js +2 -2
  17. package/dist/index.cjs +143 -76
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +39 -5
  20. package/dist/index.d.ts +39 -5
  21. package/dist/index.js +67 -16
  22. package/dist/index.js.map +1 -1
  23. package/dist/{resource-D6HfVgiA.d.cts → resource-CBTcorBJ.d.ts} +2 -2
  24. package/dist/{resource-ljs2X5NM.d.ts → resource-CaFfIB5i.d.cts} +2 -2
  25. package/dist/runtime.cjs +28 -28
  26. package/dist/runtime.js +3 -3
  27. package/dist/server.cjs +7 -7
  28. package/dist/server.d.cts +2 -2
  29. package/dist/server.d.ts +2 -2
  30. package/dist/server.js +2 -2
  31. package/dist/{signal-CRBJYQ6B.d.cts → signal-CIXTR4Qz.d.cts} +29 -1
  32. package/dist/{signal-CRBJYQ6B.d.ts → signal-CIXTR4Qz.d.ts} +29 -1
  33. package/dist/storage.cjs +66 -16
  34. package/dist/storage.cjs.map +1 -1
  35. package/dist/storage.js +66 -16
  36. package/dist/storage.js.map +1 -1
  37. package/dist/tc39-compat.cjs +3 -3
  38. package/dist/tc39-compat.d.cts +1 -1
  39. package/dist/tc39-compat.d.ts +1 -1
  40. package/dist/tc39-compat.js +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-ETPJTPYD.js.map +0 -1
  43. package/dist/chunk-H7MDUHS5.cjs.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference path="./jsx.d.ts" />
2
- import { S as SignalGetter } from './signal-CRBJYQ6B.cjs';
3
- export { a as SignalOptions, b as SignalSetter, c as createSignal } from './signal-CRBJYQ6B.cjs';
4
- export { R as Resource, a as ResourceOptions, c as createResource } from './resource-D6HfVgiA.cjs';
2
+ import { S as SignalGetter } from './signal-CIXTR4Qz.cjs';
3
+ export { a as SignalOptions, b as SignalSetter, c as createSignal, g as getSignalName, v as value } from './signal-CIXTR4Qz.cjs';
4
+ export { R as Resource, a as ResourceFetcherInfo, b as ResourceOptions, c as createResource } from './resource-CaFfIB5i.cjs';
5
5
  export { getBatchDepth, isComputed, isEffect, isEffectScope, isSignal, trigger } from 'alien-signals';
6
6
 
7
7
  declare function createEffect(fn: () => void | (() => void)): () => void;
@@ -125,6 +125,38 @@ declare function batch(fn: () => void): void;
125
125
  */
126
126
  declare function untrack<T>(fn: () => T): T;
127
127
 
128
+ /**
129
+ * Forma Reactive - Root
130
+ *
131
+ * Explicit reactive ownership scope. All effects created inside a root
132
+ * are automatically disposed when the root is torn down.
133
+ *
134
+ * Uses alien-signals' `effectScope` under the hood for native graph-level
135
+ * effect tracking, with a userland disposer list for non-effect cleanup
136
+ * (e.g., event listeners, DOM references, timers).
137
+ *
138
+ * Roots created inside another root are automatically owned by the parent
139
+ * (Solid-style). When the parent is disposed, all child roots are disposed
140
+ * too. Use {@link createUnownedRoot} for roots that must outlive their
141
+ * lexical parent (e.g., mount points, test harnesses).
142
+ */
143
+ /**
144
+ * The minimal ownership unit: something that holds disposers. A {@link RootScope}
145
+ * is an Owner with an extra alien-signals scope dispose. Effects use lightweight
146
+ * child owners (no scopeDispose) to own their nested effects generation-by-generation.
147
+ */
148
+ interface Owner {
149
+ /** Disposers to run when this owner is torn down. */
150
+ disposers: (() => void)[];
151
+ }
152
+ /** @internal — the owner disposers currently register with (or null). */
153
+ declare function getOwner(): Owner | null;
154
+ /**
155
+ * Run `fn` with `owner` installed as the current owner, restoring the previous
156
+ * owner afterwards. Lets effects/roots created asynchronously (after the
157
+ * original root callback returned) still be owned and disposed.
158
+ */
159
+ declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
128
160
  /**
129
161
  * Create a reactive root scope.
130
162
  *
@@ -831,7 +863,9 @@ declare function trackDisposer(dispose: () => void): void;
831
863
  *
832
864
  * Dependency injection via stack-based context.
833
865
  * Simpler than React's Provider component tree: provide() pushes a value,
834
- * inject() reads the top, component teardown pops automatically.
866
+ * inject() reads the top. When provide() is called during a component setup, the
867
+ * value is auto-unprovided on that component's dispose; outside a component you
868
+ * must call unprovide() yourself.
835
869
  * Zero dependencies -- native browser APIs only.
836
870
  */
837
871
  /** A typed dependency injection context created by {@link createContext}. */
@@ -1188,4 +1222,4 @@ declare function onIntersect(el: HTMLElement, handler: (entry: IntersectionObser
1188
1222
  */
1189
1223
  declare function onMutation(el: HTMLElement, handler: (mutations: MutationRecord[]) => void, options?: MutationObserverInit): () => void;
1190
1224
 
1191
- export { $, $$, type CleanupFn, type ComponentDef, type Context, type CreateListOptions, type Dispatch, type ErrorHandler, type EventBus, Fragment, type HistoryControls, type IslandHydrateFn, type KeyOptions, type ListTransitionHooks, type PersistErrorPhase, type PersistOptions, type ReconcileResult, type Ref, type SetupFn, SignalGetter, type StoreSetter, type SwitchCase, activateIslands, addClass, batch, children, cleanup, closest, createBus, createComputed, createContext, createEffect, createErrorBoundary, createHistory, createList, createMemo, createPortal, createReducer, createRef, createRoot, createShow, createStore, createSuspense, createSwitch, createText, createUnownedRoot, deactivateAllIslands, deactivateIsland, defineComponent, delegate, disposeComponent, fragment, h, hydrateIsland, inject, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, removeClass, setAttr, setHTMLUnsafe, setStyle, setText, siblings, svg, template, templateMany, toggleClass, trackDisposer, unprovide, untrack };
1225
+ export { $, $$, type CleanupFn, type ComponentDef, type Context, type CreateListOptions, type Dispatch, type ErrorHandler, type EventBus, Fragment, type HistoryControls, type IslandHydrateFn, type KeyOptions, type ListTransitionHooks, type Owner, type PersistErrorPhase, type PersistOptions, type ReconcileResult, type Ref, type SetupFn, SignalGetter, type StoreSetter, type SwitchCase, activateIslands, addClass, batch, children, cleanup, closest, createBus, createComputed, createContext, createEffect, createErrorBoundary, createHistory, createList, createMemo, createPortal, createReducer, createRef, createRoot, createShow, createStore, createSuspense, createSwitch, createText, createUnownedRoot, deactivateAllIslands, deactivateIsland, defineComponent, delegate, disposeComponent, fragment, getOwner, h, hydrateIsland, inject, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, removeClass, runWithOwner, setAttr, setHTMLUnsafe, setStyle, setText, siblings, svg, template, templateMany, toggleClass, trackDisposer, unprovide, untrack };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference path="./jsx.d.ts" />
2
- import { S as SignalGetter } from './signal-CRBJYQ6B.js';
3
- export { a as SignalOptions, b as SignalSetter, c as createSignal } from './signal-CRBJYQ6B.js';
4
- export { R as Resource, a as ResourceOptions, c as createResource } from './resource-ljs2X5NM.js';
2
+ import { S as SignalGetter } from './signal-CIXTR4Qz.js';
3
+ export { a as SignalOptions, b as SignalSetter, c as createSignal, g as getSignalName, v as value } from './signal-CIXTR4Qz.js';
4
+ export { R as Resource, a as ResourceFetcherInfo, b as ResourceOptions, c as createResource } from './resource-CBTcorBJ.js';
5
5
  export { getBatchDepth, isComputed, isEffect, isEffectScope, isSignal, trigger } from 'alien-signals';
6
6
 
7
7
  declare function createEffect(fn: () => void | (() => void)): () => void;
@@ -125,6 +125,38 @@ declare function batch(fn: () => void): void;
125
125
  */
126
126
  declare function untrack<T>(fn: () => T): T;
127
127
 
128
+ /**
129
+ * Forma Reactive - Root
130
+ *
131
+ * Explicit reactive ownership scope. All effects created inside a root
132
+ * are automatically disposed when the root is torn down.
133
+ *
134
+ * Uses alien-signals' `effectScope` under the hood for native graph-level
135
+ * effect tracking, with a userland disposer list for non-effect cleanup
136
+ * (e.g., event listeners, DOM references, timers).
137
+ *
138
+ * Roots created inside another root are automatically owned by the parent
139
+ * (Solid-style). When the parent is disposed, all child roots are disposed
140
+ * too. Use {@link createUnownedRoot} for roots that must outlive their
141
+ * lexical parent (e.g., mount points, test harnesses).
142
+ */
143
+ /**
144
+ * The minimal ownership unit: something that holds disposers. A {@link RootScope}
145
+ * is an Owner with an extra alien-signals scope dispose. Effects use lightweight
146
+ * child owners (no scopeDispose) to own their nested effects generation-by-generation.
147
+ */
148
+ interface Owner {
149
+ /** Disposers to run when this owner is torn down. */
150
+ disposers: (() => void)[];
151
+ }
152
+ /** @internal — the owner disposers currently register with (or null). */
153
+ declare function getOwner(): Owner | null;
154
+ /**
155
+ * Run `fn` with `owner` installed as the current owner, restoring the previous
156
+ * owner afterwards. Lets effects/roots created asynchronously (after the
157
+ * original root callback returned) still be owned and disposed.
158
+ */
159
+ declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
128
160
  /**
129
161
  * Create a reactive root scope.
130
162
  *
@@ -831,7 +863,9 @@ declare function trackDisposer(dispose: () => void): void;
831
863
  *
832
864
  * Dependency injection via stack-based context.
833
865
  * Simpler than React's Provider component tree: provide() pushes a value,
834
- * inject() reads the top, component teardown pops automatically.
866
+ * inject() reads the top. When provide() is called during a component setup, the
867
+ * value is auto-unprovided on that component's dispose; outside a component you
868
+ * must call unprovide() yourself.
835
869
  * Zero dependencies -- native browser APIs only.
836
870
  */
837
871
  /** A typed dependency injection context created by {@link createContext}. */
@@ -1188,4 +1222,4 @@ declare function onIntersect(el: HTMLElement, handler: (entry: IntersectionObser
1188
1222
  */
1189
1223
  declare function onMutation(el: HTMLElement, handler: (mutations: MutationRecord[]) => void, options?: MutationObserverInit): () => void;
1190
1224
 
1191
- export { $, $$, type CleanupFn, type ComponentDef, type Context, type CreateListOptions, type Dispatch, type ErrorHandler, type EventBus, Fragment, type HistoryControls, type IslandHydrateFn, type KeyOptions, type ListTransitionHooks, type PersistErrorPhase, type PersistOptions, type ReconcileResult, type Ref, type SetupFn, SignalGetter, type StoreSetter, type SwitchCase, activateIslands, addClass, batch, children, cleanup, closest, createBus, createComputed, createContext, createEffect, createErrorBoundary, createHistory, createList, createMemo, createPortal, createReducer, createRef, createRoot, createShow, createStore, createSuspense, createSwitch, createText, createUnownedRoot, deactivateAllIslands, deactivateIsland, defineComponent, delegate, disposeComponent, fragment, h, hydrateIsland, inject, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, removeClass, setAttr, setHTMLUnsafe, setStyle, setText, siblings, svg, template, templateMany, toggleClass, trackDisposer, unprovide, untrack };
1225
+ export { $, $$, type CleanupFn, type ComponentDef, type Context, type CreateListOptions, type Dispatch, type ErrorHandler, type EventBus, Fragment, type HistoryControls, type IslandHydrateFn, type KeyOptions, type ListTransitionHooks, type Owner, type PersistErrorPhase, type PersistOptions, type ReconcileResult, type Ref, type SetupFn, SignalGetter, type StoreSetter, type SwitchCase, activateIslands, addClass, batch, children, cleanup, closest, createBus, createComputed, createContext, createEffect, createErrorBoundary, createHistory, createList, createMemo, createPortal, createReducer, createRef, createRoot, createShow, createStore, createSuspense, createSwitch, createText, createUnownedRoot, deactivateAllIslands, deactivateIsland, defineComponent, delegate, disposeComponent, fragment, getOwner, h, hydrateIsland, inject, mount, nextSibling, on, onCleanup, onError, onIntersect, onKey, onMount, onMutation, onResize, onUnmount, parent, persist, prevSibling, provide, reconcileList, removeClass, runWithOwner, setAttr, setHTMLUnsafe, setStyle, setText, siblings, svg, template, templateMany, toggleClass, trackDisposer, unprovide, untrack };
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { hydrateIsland } from './chunk-AJP4OVCN.js';
2
- export { Fragment, cleanup, createList, createShow, fragment, h, hydrateIsland, reconcileList, svg } from './chunk-AJP4OVCN.js';
3
- import { internalEffect, createUnownedRoot, createRoot, untrack, registerDisposer, createEffect, pushSuspenseContext, popSuspenseContext, batch } from './chunk-Y3A2EVVS.js';
4
- export { batch, createEffect, createMemo, createReducer, createRef, createResource, createRoot, createUnownedRoot, getBatchDepth, isComputed, isEffect, isEffectScope, isSignal, on, onCleanup, trigger, untrack } from './chunk-Y3A2EVVS.js';
5
- import { createSignal, __DEV__, reportError, value } from './chunk-ETPJTPYD.js';
6
- export { createComputed, createSignal, onError } from './chunk-ETPJTPYD.js';
1
+ import { hydrateIsland } from './chunk-3U2IQIKB.js';
2
+ export { Fragment, cleanup, createList, createShow, fragment, h, hydrateIsland, reconcileList, svg } from './chunk-3U2IQIKB.js';
3
+ import { internalEffect, createUnownedRoot, createRoot, untrack, registerDisposer, createEffect, pushSuspenseContext, popSuspenseContext, batch } from './chunk-F5QUU76U.js';
4
+ export { batch, createEffect, createMemo, createReducer, createRef, createResource, createRoot, createUnownedRoot, getBatchDepth, getOwner, isComputed, isEffect, isEffectScope, isSignal, on, onCleanup, runWithOwner, trigger, untrack } from './chunk-F5QUU76U.js';
5
+ import { createSignal, __DEV__, reportError, value } from './chunk-FAIWRZKJ.js';
6
+ export { createComputed, createSignal, getSignalName, onError, value } from './chunk-FAIWRZKJ.js';
7
7
 
8
8
  // src/dom/text.ts
9
9
  function createText(value2) {
@@ -405,6 +405,13 @@ function onUnmount(fn) {
405
405
  }
406
406
  currentLifecycleContext.unmountCallbacks.push(fn);
407
407
  }
408
+ function registerContextDisposer(dispose) {
409
+ if (currentLifecycleContext !== null) {
410
+ currentLifecycleContext.contextDisposers.push(dispose);
411
+ return true;
412
+ }
413
+ return false;
414
+ }
408
415
  var DISPOSE_KEY = /* @__PURE__ */ Symbol("forma:component:dispose");
409
416
  function defineComponent(setupOrDef) {
410
417
  const setup = typeof setupOrDef === "function" ? setupOrDef : setupOrDef.setup;
@@ -413,16 +420,29 @@ function defineComponent(setupOrDef) {
413
420
  const ctx = {
414
421
  disposers: [],
415
422
  mountCallbacks: [],
416
- unmountCallbacks: []
423
+ unmountCallbacks: [],
424
+ contextDisposers: []
417
425
  };
418
426
  pushLifecycleContext(ctx);
419
427
  let dom;
420
428
  try {
421
429
  dom = setup();
430
+ } catch (e) {
431
+ for (let i = ctx.contextDisposers.length - 1; i >= 0; i--) {
432
+ try {
433
+ ctx.contextDisposers[i]();
434
+ } catch {
435
+ }
436
+ }
437
+ ctx.contextDisposers.length = 0;
438
+ throw e;
422
439
  } finally {
423
440
  popLifecycleContext();
424
441
  }
442
+ let disposed = false;
425
443
  const dispose = () => {
444
+ if (disposed) return;
445
+ disposed = true;
426
446
  for (const cb of ctx.unmountCallbacks) {
427
447
  try {
428
448
  cb();
@@ -437,20 +457,38 @@ function defineComponent(setupOrDef) {
437
457
  reportError(e, "component disposer");
438
458
  }
439
459
  }
460
+ for (let i = ctx.contextDisposers.length - 1; i >= 0; i--) {
461
+ try {
462
+ ctx.contextDisposers[i]();
463
+ } catch (e) {
464
+ reportError(e, "context disposer");
465
+ }
466
+ }
440
467
  ctx.disposers.length = 0;
441
468
  ctx.mountCallbacks.length = 0;
442
469
  ctx.unmountCallbacks.length = 0;
470
+ ctx.contextDisposers.length = 0;
443
471
  };
444
472
  dom[DISPOSE_KEY] = dispose;
445
- for (const cb of ctx.mountCallbacks) {
446
- try {
447
- const cleanup2 = cb();
448
- if (typeof cleanup2 === "function") {
449
- ctx.unmountCallbacks.push(cleanup2);
473
+ if (dom.nodeType === 11) {
474
+ for (const child of Array.from(dom.childNodes)) {
475
+ child[DISPOSE_KEY] = dispose;
476
+ }
477
+ }
478
+ pushLifecycleContext(ctx);
479
+ try {
480
+ for (const cb of ctx.mountCallbacks) {
481
+ try {
482
+ const cleanup2 = cb();
483
+ if (typeof cleanup2 === "function") {
484
+ ctx.unmountCallbacks.push(cleanup2);
485
+ }
486
+ } catch (e) {
487
+ reportError(e, "onMount");
450
488
  }
451
- } catch (e) {
452
- reportError(e, "onMount");
453
489
  }
490
+ } finally {
491
+ popLifecycleContext();
454
492
  }
455
493
  return dom;
456
494
  };
@@ -470,6 +508,17 @@ function trackDisposer(dispose) {
470
508
 
471
509
  // src/component/context.ts
472
510
  var contextStacks = /* @__PURE__ */ new Map();
511
+ function removeFrame(id, token) {
512
+ const stack = contextStacks.get(id);
513
+ if (!stack) return;
514
+ for (let i = stack.length - 1; i >= 0; i--) {
515
+ if (stack[i].token === token) {
516
+ stack.splice(i, 1);
517
+ break;
518
+ }
519
+ }
520
+ if (stack.length === 0) contextStacks.delete(id);
521
+ }
473
522
  function createContext(defaultValue) {
474
523
  return {
475
524
  id: /* @__PURE__ */ Symbol("forma:context"),
@@ -482,14 +531,16 @@ function provide(ctx, value2) {
482
531
  stack = [];
483
532
  contextStacks.set(ctx.id, stack);
484
533
  }
485
- stack.push(value2);
534
+ const token = /* @__PURE__ */ Symbol("forma:context-frame");
535
+ stack.push({ token, value: value2 });
536
+ registerContextDisposer(() => removeFrame(ctx.id, token));
486
537
  }
487
538
  function inject(ctx) {
488
539
  const stack = contextStacks.get(ctx.id);
489
540
  if (stack === void 0 || stack.length === 0) {
490
541
  return ctx.defaultValue;
491
542
  }
492
- return stack[stack.length - 1];
543
+ return stack[stack.length - 1].value;
493
544
  }
494
545
  function unprovide(ctx) {
495
546
  const stack = contextStacks.get(ctx.id);