@fictjs/runtime 0.0.14 → 0.1.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 (40) hide show
  1. package/dist/advanced.cjs +8 -8
  2. package/dist/advanced.js +3 -3
  3. package/dist/{chunk-PMF6MWEV.cjs → chunk-7WAGAQLT.cjs} +45 -24
  4. package/dist/chunk-7WAGAQLT.cjs.map +1 -0
  5. package/dist/{chunk-RY4WDS6R.js → chunk-BWZFJXUI.js} +32 -11
  6. package/dist/chunk-BWZFJXUI.js.map +1 -0
  7. package/dist/{chunk-F3AIYQB7.js → chunk-CF3OHML2.js} +3 -3
  8. package/dist/chunk-CF3OHML2.js.map +1 -0
  9. package/dist/{chunk-GJTYOFMO.cjs → chunk-Q4EN6BXV.cjs} +16 -16
  10. package/dist/{chunk-GJTYOFMO.cjs.map → chunk-Q4EN6BXV.cjs.map} +1 -1
  11. package/dist/{chunk-IUZXKAAY.js → chunk-V62XZLDU.js} +2 -2
  12. package/dist/{chunk-624QY53A.cjs → chunk-YQ4IB7NC.cjs} +7 -7
  13. package/dist/chunk-YQ4IB7NC.cjs.map +1 -0
  14. package/dist/index.cjs +44 -44
  15. package/dist/index.d.cts +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.dev.js +30 -9
  18. package/dist/index.dev.js.map +1 -1
  19. package/dist/index.js +2 -2
  20. package/dist/internal.cjs +44 -35
  21. package/dist/internal.cjs.map +1 -1
  22. package/dist/internal.d.cts +6 -1
  23. package/dist/internal.d.ts +6 -1
  24. package/dist/internal.js +12 -3
  25. package/dist/internal.js.map +1 -1
  26. package/dist/{props-ES0Ag_Wd.d.ts → props-BBi8Tkks.d.ts} +9 -2
  27. package/dist/{props-CrOMYbLv.d.cts → props-BfmSLuyp.d.cts} +9 -2
  28. package/package.json +1 -1
  29. package/src/binding.ts +4 -3
  30. package/src/constants.ts +2 -3
  31. package/src/dev-entry.ts +22 -0
  32. package/src/lifecycle.ts +11 -3
  33. package/src/list-helpers.ts +14 -3
  34. package/src/props.ts +29 -3
  35. package/src/scope.ts +1 -1
  36. package/dist/chunk-624QY53A.cjs.map +0 -1
  37. package/dist/chunk-F3AIYQB7.js.map +0 -1
  38. package/dist/chunk-PMF6MWEV.cjs.map +0 -1
  39. package/dist/chunk-RY4WDS6R.js.map +0 -1
  40. /package/dist/{chunk-IUZXKAAY.js.map → chunk-V62XZLDU.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  isReactive,
5
5
  onCleanup,
6
6
  registerRootCleanup
7
- } from "./chunk-RY4WDS6R.js";
7
+ } from "./chunk-BWZFJXUI.js";
8
8
 
9
9
  // src/scope.ts
10
10
  function createScope() {
@@ -17,7 +17,7 @@ function createScope() {
17
17
  };
18
18
  const run = (fn) => {
19
19
  stop();
20
- const { dispose: rootDispose, value } = createRoot(fn);
20
+ const { dispose: rootDispose, value } = createRoot(fn, { inherit: true });
21
21
  dispose = rootDispose;
22
22
  return value;
23
23
  };
@@ -42,4 +42,4 @@ export {
42
42
  createScope,
43
43
  runInScope
44
44
  };
45
- //# sourceMappingURL=chunk-F3AIYQB7.js.map
45
+ //# sourceMappingURL=chunk-CF3OHML2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scope.ts"],"sourcesContent":["import { isReactive, type MaybeReactive } from './binding'\nimport { createEffect } from './effect'\nimport { createRoot, onCleanup, registerRootCleanup } from './lifecycle'\n\nexport { effectScope } from './signal'\n\nexport interface ReactiveScope {\n run<T>(fn: () => T): T\n stop(): void\n}\n\n/**\n * Create an explicit reactive scope that can contain effects/memos and be stopped manually.\n * The scope registers with the current root for cleanup.\n */\nexport function createScope(): ReactiveScope {\n let dispose: (() => void) | null = null\n\n const stop = () => {\n if (dispose) {\n dispose()\n dispose = null\n }\n }\n\n const run = <T>(fn: () => T): T => {\n stop()\n const { dispose: rootDispose, value } = createRoot(fn, { inherit: true })\n dispose = rootDispose\n return value\n }\n\n registerRootCleanup(stop)\n return { run, stop }\n}\n\n/**\n * Run a block of reactive code inside a managed scope that follows a boolean flag.\n * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.\n */\nexport function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void {\n const scope = createScope()\n const evaluate = () => (isReactive(flag) ? (flag as () => boolean)() : !!flag)\n\n createEffect(() => {\n const enabled = evaluate()\n if (enabled) {\n scope.run(fn)\n } else {\n scope.stop()\n }\n })\n\n onCleanup(scope.stop)\n}\n"],"mappings":";;;;;;;;;AAeO,SAAS,cAA6B;AAC3C,MAAI,UAA+B;AAEnC,QAAM,OAAO,MAAM;AACjB,QAAI,SAAS;AACX,cAAQ;AACR,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,MAAM,CAAI,OAAmB;AACjC,SAAK;AACL,UAAM,EAAE,SAAS,aAAa,MAAM,IAAI,WAAW,IAAI,EAAE,SAAS,KAAK,CAAC;AACxE,cAAU;AACV,WAAO;AAAA,EACT;AAEA,sBAAoB,IAAI;AACxB,SAAO,EAAE,KAAK,KAAK;AACrB;AAMO,SAAS,WAAW,MAA8B,IAAsB;AAC7E,QAAM,QAAQ,YAAY;AAC1B,QAAM,WAAW,MAAO,WAAW,IAAI,IAAK,KAAuB,IAAI,CAAC,CAAC;AAEzE,eAAa,MAAM;AACjB,UAAM,UAAU,SAAS;AACzB,QAAI,SAAS;AACX,YAAM,IAAI,EAAE;AAAA,IACd,OAAO;AACL,YAAM,KAAK;AAAA,IACb;AAAA,EACF,CAAC;AAED,YAAU,MAAM,IAAI;AACtB;","names":[]}
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- var _chunkPMF6MWEVcjs = require('./chunk-PMF6MWEV.cjs');
13
+ var _chunk7WAGAQLTcjs = require('./chunk-7WAGAQLT.cjs');
14
14
 
15
15
  // src/context.ts
16
16
  var contextStorage = /* @__PURE__ */ new WeakMap();
@@ -30,8 +30,8 @@ function createContext(defaultValue) {
30
30
  Provider: null
31
31
  };
32
32
  context.Provider = function Provider(props) {
33
- const hostRoot = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
34
- const providerRoot = _chunkPMF6MWEVcjs.createRootContext.call(void 0, hostRoot);
33
+ const hostRoot = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
34
+ const providerRoot = _chunk7WAGAQLTcjs.createRootContext.call(void 0, hostRoot);
35
35
  const contextMap = getContextMap(providerRoot);
36
36
  contextMap.set(id, props.value);
37
37
  const fragment = document.createDocumentFragment();
@@ -45,32 +45,32 @@ function createContext(defaultValue) {
45
45
  cleanup = void 0;
46
46
  }
47
47
  if (activeNodes.length) {
48
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, activeNodes);
48
+ _chunk7WAGAQLTcjs.removeNodes.call(void 0, activeNodes);
49
49
  activeNodes = [];
50
50
  }
51
51
  if (children == null || children === false) {
52
52
  return;
53
53
  }
54
- const prev = _chunkPMF6MWEVcjs.pushRoot.call(void 0, providerRoot);
54
+ const prev = _chunk7WAGAQLTcjs.pushRoot.call(void 0, providerRoot);
55
55
  let nodes = [];
56
56
  try {
57
- const output = _chunkPMF6MWEVcjs.createElement.call(void 0, children);
58
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, output);
57
+ const output = _chunk7WAGAQLTcjs.createElement.call(void 0, children);
58
+ nodes = _chunk7WAGAQLTcjs.toNodeArray.call(void 0, output);
59
59
  const parentNode = marker.parentNode;
60
60
  if (parentNode) {
61
- _chunkPMF6MWEVcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
61
+ _chunk7WAGAQLTcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
62
62
  }
63
63
  } finally {
64
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
65
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, providerRoot);
64
+ _chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
65
+ _chunk7WAGAQLTcjs.flushOnMount.call(void 0, providerRoot);
66
66
  }
67
67
  cleanup = () => {
68
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, providerRoot);
69
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, nodes);
68
+ _chunk7WAGAQLTcjs.destroyRoot.call(void 0, providerRoot);
69
+ _chunk7WAGAQLTcjs.removeNodes.call(void 0, nodes);
70
70
  };
71
71
  activeNodes = nodes;
72
72
  };
73
- _chunkPMF6MWEVcjs.createRenderEffect.call(void 0, () => {
73
+ _chunk7WAGAQLTcjs.createRenderEffect.call(void 0, () => {
74
74
  contextMap.set(id, props.value);
75
75
  renderChildren(props.children);
76
76
  });
@@ -79,7 +79,7 @@ function createContext(defaultValue) {
79
79
  return context;
80
80
  }
81
81
  function useContext(context) {
82
- let root = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
82
+ let root = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
83
83
  while (root) {
84
84
  const contextMap = contextStorage.get(root);
85
85
  if (contextMap && contextMap.has(context.id)) {
@@ -90,7 +90,7 @@ function useContext(context) {
90
90
  return context.defaultValue;
91
91
  }
92
92
  function hasContext(context) {
93
- let root = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
93
+ let root = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
94
94
  while (root) {
95
95
  const contextMap = contextStorage.get(root);
96
96
  if (contextMap && contextMap.has(context.id)) {
@@ -106,4 +106,4 @@ function hasContext(context) {
106
106
 
107
107
 
108
108
  exports.createContext = createContext; exports.useContext = useContext; exports.hasContext = hasContext;
109
- //# sourceMappingURL=chunk-GJTYOFMO.cjs.map
109
+ //# sourceMappingURL=chunk-Q4EN6BXV.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-GJTYOFMO.cjs","../src/context.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-GJTYOFMO.cjs","sourcesContent":[null,"/**\n * @fileoverview Context API for Fict\n *\n * Provides a way to pass data through the component tree without having to pass\n * props down manually at every level. Context is designed for:\n *\n * - SSR isolation (different request = different context values)\n * - Multi-instance support (multiple app roots with different values)\n * - Subtree scoping (override values in specific parts of the tree)\n *\n * ## Design Principles\n *\n * 1. **Reuses existing RootContext hierarchy** - Uses parent chain for value lookup,\n * consistent with handleError/handleSuspend mechanisms.\n *\n * 2. **Zero extra root creation overhead** - Provider doesn't create new root,\n * only mounts value on current root.\n *\n * 3. **Auto-aligned with insert/suspense boundaries** - Because they create child\n * roots that inherit parent, context values propagate correctly.\n *\n * ## Usage\n *\n * ```tsx\n * // Create context with default value\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Provide value to subtree\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <ThemedComponent />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume value\n * function ThemedComponent() {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>...</div>\n * }\n * ```\n *\n * @module\n */\n\nimport { createElement } from './dom'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n popRoot,\n pushRoot,\n type RootContext,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createRenderEffect } from './effect'\nimport type { BaseProps, FictNode } from './types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Context object created by createContext.\n * Contains the Provider component and serves as a key for context lookup.\n */\nexport interface Context<T> {\n /** Unique identifier for this context */\n readonly id: symbol\n /** Default value when no provider is found */\n readonly defaultValue: T\n /** Provider component for supplying context values */\n Provider: ContextProvider<T>\n /** Display name for debugging */\n displayName?: string\n}\n\n/**\n * Props for the Context Provider component\n */\nexport interface ProviderProps<T> extends BaseProps {\n /** The value to provide to the subtree */\n value: T\n}\n\n/**\n * Provider component type\n */\nexport type ContextProvider<T> = (props: ProviderProps<T>) => FictNode\n\n// ============================================================================\n// Internal Context Storage\n// ============================================================================\n\n/**\n * WeakMap to store context values per RootContext.\n * Using WeakMap ensures proper garbage collection when roots are destroyed.\n */\nconst contextStorage = new WeakMap<RootContext, Map<symbol, unknown>>()\n\n/**\n * Get the context map for a root, creating it if needed\n */\nfunction getContextMap(root: RootContext): Map<symbol, unknown> {\n let map = contextStorage.get(root)\n if (!map) {\n map = new Map()\n contextStorage.set(root, map)\n }\n return map\n}\n\n// ============================================================================\n// Context API\n// ============================================================================\n\n/**\n * Creates a new context with the given default value.\n *\n * Context provides a way to pass values through the component tree without\n * explicit props drilling. It's especially useful for:\n *\n * - Theme data\n * - Locale/i18n settings\n * - Authentication state\n * - Feature flags\n * - Any data that many components at different nesting levels need\n *\n * @param defaultValue - The value to use when no Provider is found above in the tree\n * @returns A context object with a Provider component\n *\n * @example\n * ```tsx\n * // Create a theme context\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Use the provider\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <Content />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume the context\n * function Content() {\n * const theme = useContext(ThemeContext)\n * return <div class={`theme-${theme}`}>Hello</div>\n * }\n * ```\n */\nexport function createContext<T>(defaultValue: T): Context<T> {\n const id = Symbol('fict.context')\n\n const context: Context<T> = {\n id,\n defaultValue,\n Provider: null as unknown as ContextProvider<T>,\n }\n\n // Create the Provider component\n context.Provider = function Provider(props: ProviderProps<T>): FictNode {\n const hostRoot = getCurrentRoot()\n\n // Create a child root for the provider's subtree\n // This establishes the provider boundary - children will look up from here\n const providerRoot = createRootContext(hostRoot)\n\n // Store the context value on this root\n const contextMap = getContextMap(providerRoot)\n contextMap.set(id, props.value)\n\n // Create DOM structure\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:ctx')\n fragment.appendChild(marker)\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const renderChildren = (children: FictNode) => {\n // Cleanup previous render\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (children == null || children === false) {\n return\n }\n\n const prev = pushRoot(providerRoot)\n let nodes: Node[] = []\n try {\n const output = createElement(children)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } finally {\n popRoot(prev)\n flushOnMount(providerRoot)\n }\n\n cleanup = () => {\n destroyRoot(providerRoot)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n // Initial render\n createRenderEffect(() => {\n // Update context value on re-render (if value prop changes reactively)\n contextMap.set(id, props.value)\n renderChildren(props.children)\n })\n\n return fragment\n }\n\n return context\n}\n\n/**\n * Reads the current value of a context.\n *\n * useContext looks up through the RootContext parent chain to find the\n * nearest Provider for this context. If no Provider is found, returns\n * the context's default value.\n *\n * @param context - The context object created by createContext\n * @returns The current context value\n *\n * @example\n * ```tsx\n * const ThemeContext = createContext('light')\n *\n * function ThemedButton() {\n * const theme = useContext(ThemeContext)\n * return <button class={theme === 'dark' ? 'btn-dark' : 'btn-light'}>Click</button>\n * }\n * ```\n */\nexport function useContext<T>(context: Context<T>): T {\n let root = getCurrentRoot()\n\n // Walk up the parent chain looking for the context value\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return contextMap.get(context.id) as T\n }\n root = root.parent\n }\n\n // No provider found, return default value\n return context.defaultValue\n}\n\n/**\n * Checks if a context value is currently provided in the tree.\n *\n * Useful for conditional behavior when a provider may or may not exist.\n *\n * @param context - The context object to check\n * @returns true if a Provider exists above in the tree\n *\n * @example\n * ```tsx\n * function OptionalTheme() {\n * if (hasContext(ThemeContext)) {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>Themed content</div>\n * }\n * return <div>Default content</div>\n * }\n * ```\n */\nexport function hasContext<T>(context: Context<T>): boolean {\n let root = getCurrentRoot()\n\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return true\n }\n root = root.parent\n }\n\n return false\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-Q4EN6BXV.cjs","../src/context.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-Q4EN6BXV.cjs","sourcesContent":[null,"/**\n * @fileoverview Context API for Fict\n *\n * Provides a way to pass data through the component tree without having to pass\n * props down manually at every level. Context is designed for:\n *\n * - SSR isolation (different request = different context values)\n * - Multi-instance support (multiple app roots with different values)\n * - Subtree scoping (override values in specific parts of the tree)\n *\n * ## Design Principles\n *\n * 1. **Reuses existing RootContext hierarchy** - Uses parent chain for value lookup,\n * consistent with handleError/handleSuspend mechanisms.\n *\n * 2. **Zero extra root creation overhead** - Provider doesn't create new root,\n * only mounts value on current root.\n *\n * 3. **Auto-aligned with insert/suspense boundaries** - Because they create child\n * roots that inherit parent, context values propagate correctly.\n *\n * ## Usage\n *\n * ```tsx\n * // Create context with default value\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Provide value to subtree\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <ThemedComponent />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume value\n * function ThemedComponent() {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>...</div>\n * }\n * ```\n *\n * @module\n */\n\nimport { createElement } from './dom'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n popRoot,\n pushRoot,\n type RootContext,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createRenderEffect } from './effect'\nimport type { BaseProps, FictNode } from './types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Context object created by createContext.\n * Contains the Provider component and serves as a key for context lookup.\n */\nexport interface Context<T> {\n /** Unique identifier for this context */\n readonly id: symbol\n /** Default value when no provider is found */\n readonly defaultValue: T\n /** Provider component for supplying context values */\n Provider: ContextProvider<T>\n /** Display name for debugging */\n displayName?: string\n}\n\n/**\n * Props for the Context Provider component\n */\nexport interface ProviderProps<T> extends BaseProps {\n /** The value to provide to the subtree */\n value: T\n}\n\n/**\n * Provider component type\n */\nexport type ContextProvider<T> = (props: ProviderProps<T>) => FictNode\n\n// ============================================================================\n// Internal Context Storage\n// ============================================================================\n\n/**\n * WeakMap to store context values per RootContext.\n * Using WeakMap ensures proper garbage collection when roots are destroyed.\n */\nconst contextStorage = new WeakMap<RootContext, Map<symbol, unknown>>()\n\n/**\n * Get the context map for a root, creating it if needed\n */\nfunction getContextMap(root: RootContext): Map<symbol, unknown> {\n let map = contextStorage.get(root)\n if (!map) {\n map = new Map()\n contextStorage.set(root, map)\n }\n return map\n}\n\n// ============================================================================\n// Context API\n// ============================================================================\n\n/**\n * Creates a new context with the given default value.\n *\n * Context provides a way to pass values through the component tree without\n * explicit props drilling. It's especially useful for:\n *\n * - Theme data\n * - Locale/i18n settings\n * - Authentication state\n * - Feature flags\n * - Any data that many components at different nesting levels need\n *\n * @param defaultValue - The value to use when no Provider is found above in the tree\n * @returns A context object with a Provider component\n *\n * @example\n * ```tsx\n * // Create a theme context\n * const ThemeContext = createContext<'light' | 'dark'>('light')\n *\n * // Use the provider\n * function App() {\n * return (\n * <ThemeContext.Provider value=\"dark\">\n * <Content />\n * </ThemeContext.Provider>\n * )\n * }\n *\n * // Consume the context\n * function Content() {\n * const theme = useContext(ThemeContext)\n * return <div class={`theme-${theme}`}>Hello</div>\n * }\n * ```\n */\nexport function createContext<T>(defaultValue: T): Context<T> {\n const id = Symbol('fict.context')\n\n const context: Context<T> = {\n id,\n defaultValue,\n Provider: null as unknown as ContextProvider<T>,\n }\n\n // Create the Provider component\n context.Provider = function Provider(props: ProviderProps<T>): FictNode {\n const hostRoot = getCurrentRoot()\n\n // Create a child root for the provider's subtree\n // This establishes the provider boundary - children will look up from here\n const providerRoot = createRootContext(hostRoot)\n\n // Store the context value on this root\n const contextMap = getContextMap(providerRoot)\n contextMap.set(id, props.value)\n\n // Create DOM structure\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:ctx')\n fragment.appendChild(marker)\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const renderChildren = (children: FictNode) => {\n // Cleanup previous render\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (children == null || children === false) {\n return\n }\n\n const prev = pushRoot(providerRoot)\n let nodes: Node[] = []\n try {\n const output = createElement(children)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } finally {\n popRoot(prev)\n flushOnMount(providerRoot)\n }\n\n cleanup = () => {\n destroyRoot(providerRoot)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n // Initial render\n createRenderEffect(() => {\n // Update context value on re-render (if value prop changes reactively)\n contextMap.set(id, props.value)\n renderChildren(props.children)\n })\n\n return fragment\n }\n\n return context\n}\n\n/**\n * Reads the current value of a context.\n *\n * useContext looks up through the RootContext parent chain to find the\n * nearest Provider for this context. If no Provider is found, returns\n * the context's default value.\n *\n * @param context - The context object created by createContext\n * @returns The current context value\n *\n * @example\n * ```tsx\n * const ThemeContext = createContext('light')\n *\n * function ThemedButton() {\n * const theme = useContext(ThemeContext)\n * return <button class={theme === 'dark' ? 'btn-dark' : 'btn-light'}>Click</button>\n * }\n * ```\n */\nexport function useContext<T>(context: Context<T>): T {\n let root = getCurrentRoot()\n\n // Walk up the parent chain looking for the context value\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return contextMap.get(context.id) as T\n }\n root = root.parent\n }\n\n // No provider found, return default value\n return context.defaultValue\n}\n\n/**\n * Checks if a context value is currently provided in the tree.\n *\n * Useful for conditional behavior when a provider may or may not exist.\n *\n * @param context - The context object to check\n * @returns true if a Provider exists above in the tree\n *\n * @example\n * ```tsx\n * function OptionalTheme() {\n * if (hasContext(ThemeContext)) {\n * const theme = useContext(ThemeContext)\n * return <div class={theme}>Themed content</div>\n * }\n * return <div>Default content</div>\n * }\n * ```\n */\nexport function hasContext<T>(context: Context<T>): boolean {\n let root = getCurrentRoot()\n\n while (root) {\n const contextMap = contextStorage.get(root)\n if (contextMap && contextMap.has(context.id)) {\n return true\n }\n root = root.parent\n }\n\n return false\n}\n"]}
@@ -10,7 +10,7 @@ import {
10
10
  pushRoot,
11
11
  removeNodes,
12
12
  toNodeArray
13
- } from "./chunk-RY4WDS6R.js";
13
+ } from "./chunk-BWZFJXUI.js";
14
14
 
15
15
  // src/context.ts
16
16
  var contextStorage = /* @__PURE__ */ new WeakMap();
@@ -106,4 +106,4 @@ export {
106
106
  useContext,
107
107
  hasContext
108
108
  };
109
- //# sourceMappingURL=chunk-IUZXKAAY.js.map
109
+ //# sourceMappingURL=chunk-V62XZLDU.js.map
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkPMF6MWEVcjs = require('./chunk-PMF6MWEV.cjs');
7
+ var _chunk7WAGAQLTcjs = require('./chunk-7WAGAQLT.cjs');
8
8
 
9
9
  // src/scope.ts
10
10
  function createScope() {
@@ -17,17 +17,17 @@ function createScope() {
17
17
  };
18
18
  const run = (fn) => {
19
19
  stop();
20
- const { dispose: rootDispose, value } = _chunkPMF6MWEVcjs.createRoot.call(void 0, fn);
20
+ const { dispose: rootDispose, value } = _chunk7WAGAQLTcjs.createRoot.call(void 0, fn, { inherit: true });
21
21
  dispose = rootDispose;
22
22
  return value;
23
23
  };
24
- _chunkPMF6MWEVcjs.registerRootCleanup.call(void 0, stop);
24
+ _chunk7WAGAQLTcjs.registerRootCleanup.call(void 0, stop);
25
25
  return { run, stop };
26
26
  }
27
27
  function runInScope(flag, fn) {
28
28
  const scope = createScope();
29
- const evaluate = () => _chunkPMF6MWEVcjs.isReactive.call(void 0, flag) ? flag() : !!flag;
30
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
29
+ const evaluate = () => _chunk7WAGAQLTcjs.isReactive.call(void 0, flag) ? flag() : !!flag;
30
+ _chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
31
31
  const enabled = evaluate();
32
32
  if (enabled) {
33
33
  scope.run(fn);
@@ -35,11 +35,11 @@ function runInScope(flag, fn) {
35
35
  scope.stop();
36
36
  }
37
37
  });
38
- _chunkPMF6MWEVcjs.onCleanup.call(void 0, scope.stop);
38
+ _chunk7WAGAQLTcjs.onCleanup.call(void 0, scope.stop);
39
39
  }
40
40
 
41
41
 
42
42
 
43
43
 
44
44
  exports.createScope = createScope; exports.runInScope = runInScope;
45
- //# sourceMappingURL=chunk-624QY53A.cjs.map
45
+ //# sourceMappingURL=chunk-YQ4IB7NC.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/chunk-YQ4IB7NC.cjs","../src/scope.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACOO,SAAS,WAAA,CAAA,EAA6B;AAC3C,EAAA,IAAI,QAAA,EAA+B,IAAA;AAEnC,EAAA,MAAM,KAAA,EAAO,CAAA,EAAA,GAAM;AACjB,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,IAAA;AAAA,IACZ;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,IAAA,EAAM,CAAI,EAAA,EAAA,GAAmB;AACjC,IAAA,IAAA,CAAK,CAAA;AACL,IAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,MAAM,EAAA,EAAI,0CAAA,EAAW,EAAI,EAAE,OAAA,EAAS,KAAK,CAAC,CAAA;AACxE,IAAA,QAAA,EAAU,WAAA;AACV,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAEA,EAAA,mDAAA,IAAwB,CAAA;AACxB,EAAA,OAAO,EAAE,GAAA,EAAK,KAAK,CAAA;AACrB;AAMO,SAAS,UAAA,CAAW,IAAA,EAA8B,EAAA,EAAsB;AAC7E,EAAA,MAAM,MAAA,EAAQ,WAAA,CAAY,CAAA;AAC1B,EAAA,MAAM,SAAA,EAAW,CAAA,EAAA,GAAO,0CAAA,IAAe,EAAA,EAAK,IAAA,CAAuB,EAAA,EAAI,CAAC,CAAC,IAAA;AAEzE,EAAA,4CAAA,CAAa,EAAA,GAAM;AACjB,IAAA,MAAM,QAAA,EAAU,QAAA,CAAS,CAAA;AACzB,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AAAA,IACd,EAAA,KAAO;AACL,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA;AAAA,IACb;AAAA,EACF,CAAC,CAAA;AAED,EAAA,yCAAA,KAAU,CAAM,IAAI,CAAA;AACtB;ADfA;AACA;AACE;AACA;AACF,mEAAC","file":"/home/runner/work/fict/fict/packages/runtime/dist/chunk-YQ4IB7NC.cjs","sourcesContent":[null,"import { isReactive, type MaybeReactive } from './binding'\nimport { createEffect } from './effect'\nimport { createRoot, onCleanup, registerRootCleanup } from './lifecycle'\n\nexport { effectScope } from './signal'\n\nexport interface ReactiveScope {\n run<T>(fn: () => T): T\n stop(): void\n}\n\n/**\n * Create an explicit reactive scope that can contain effects/memos and be stopped manually.\n * The scope registers with the current root for cleanup.\n */\nexport function createScope(): ReactiveScope {\n let dispose: (() => void) | null = null\n\n const stop = () => {\n if (dispose) {\n dispose()\n dispose = null\n }\n }\n\n const run = <T>(fn: () => T): T => {\n stop()\n const { dispose: rootDispose, value } = createRoot(fn, { inherit: true })\n dispose = rootDispose\n return value\n }\n\n registerRootCleanup(stop)\n return { run, stop }\n}\n\n/**\n * Run a block of reactive code inside a managed scope that follows a boolean flag.\n * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.\n */\nexport function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void {\n const scope = createScope()\n const evaluate = () => (isReactive(flag) ? (flag as () => boolean)() : !!flag)\n\n createEffect(() => {\n const enabled = evaluate()\n if (enabled) {\n scope.run(fn)\n } else {\n scope.stop()\n }\n })\n\n onCleanup(scope.stop)\n}\n"]}
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkGJTYOFMOcjs = require('./chunk-GJTYOFMO.cjs');
5
+ var _chunkQ4EN6BXVcjs = require('./chunk-Q4EN6BXV.cjs');
6
6
 
7
7
 
8
8
 
@@ -34,7 +34,7 @@ var _chunkGJTYOFMOcjs = require('./chunk-GJTYOFMO.cjs');
34
34
 
35
35
 
36
36
 
37
- var _chunkPMF6MWEVcjs = require('./chunk-PMF6MWEV.cjs');
37
+ var _chunk7WAGAQLTcjs = require('./chunk-7WAGAQLT.cjs');
38
38
 
39
39
  // src/ref.ts
40
40
  function createRef() {
@@ -46,8 +46,8 @@ function ErrorBoundary(props) {
46
46
  const fragment = document.createDocumentFragment();
47
47
  const marker = document.createComment("fict:error-boundary");
48
48
  fragment.appendChild(marker);
49
- const currentView = _chunkPMF6MWEVcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
50
- const hostRoot = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
49
+ const currentView = _chunk7WAGAQLTcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
50
+ const hostRoot = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
51
51
  let cleanup;
52
52
  let activeNodes = [];
53
53
  let renderingFallback = false;
@@ -63,26 +63,26 @@ function ErrorBoundary(props) {
63
63
  cleanup = void 0;
64
64
  }
65
65
  if (activeNodes.length) {
66
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, activeNodes);
66
+ _chunk7WAGAQLTcjs.removeNodes.call(void 0, activeNodes);
67
67
  activeNodes = [];
68
68
  }
69
69
  if (value == null || value === false) {
70
70
  return;
71
71
  }
72
- const root = _chunkPMF6MWEVcjs.createRootContext.call(void 0, hostRoot);
73
- const prev = _chunkPMF6MWEVcjs.pushRoot.call(void 0, root);
72
+ const root = _chunk7WAGAQLTcjs.createRootContext.call(void 0, hostRoot);
73
+ const prev = _chunk7WAGAQLTcjs.pushRoot.call(void 0, root);
74
74
  let nodes = [];
75
75
  try {
76
- const output = _chunkPMF6MWEVcjs.createElement.call(void 0, value);
77
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, output);
76
+ const output = _chunk7WAGAQLTcjs.createElement.call(void 0, value);
77
+ nodes = _chunk7WAGAQLTcjs.toNodeArray.call(void 0, output);
78
78
  const parentNode = marker.parentNode;
79
79
  if (parentNode) {
80
- _chunkPMF6MWEVcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
80
+ _chunk7WAGAQLTcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
81
81
  }
82
82
  } catch (err) {
83
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
84
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
85
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
83
+ _chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
84
+ _chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
85
+ _chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
86
86
  if (renderingFallback) {
87
87
  throw err;
88
88
  }
@@ -97,19 +97,19 @@ function ErrorBoundary(props) {
97
97
  }
98
98
  return;
99
99
  }
100
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
101
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
100
+ _chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
101
+ _chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
102
102
  cleanup = () => {
103
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
104
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, nodes);
103
+ _chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
104
+ _chunk7WAGAQLTcjs.removeNodes.call(void 0, nodes);
105
105
  };
106
106
  activeNodes = nodes;
107
107
  };
108
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
108
+ _chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
109
109
  const value = currentView();
110
110
  renderValue(value);
111
111
  });
112
- _chunkPMF6MWEVcjs.registerErrorHandler.call(void 0, (err) => {
112
+ _chunk7WAGAQLTcjs.registerErrorHandler.call(void 0, (err) => {
113
113
  renderValue(toView(err));
114
114
  _optionalChain([props, 'access', _5 => _5.onError, 'optionalCall', _6 => _6(err)]);
115
115
  return true;
@@ -118,7 +118,7 @@ function ErrorBoundary(props) {
118
118
  const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
119
119
  const getter = isGetter ? props.resetKeys : void 0;
120
120
  let prev = isGetter ? getter() : props.resetKeys;
121
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
121
+ _chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
122
122
  const next = getter ? getter() : props.resetKeys;
123
123
  if (prev !== next) {
124
124
  prev = next;
@@ -147,11 +147,11 @@ function createSuspenseToken() {
147
147
  }
148
148
  var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
149
149
  function Suspense(props) {
150
- const currentView = _chunkPMF6MWEVcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
151
- const pending = _chunkPMF6MWEVcjs.signal.call(void 0, 0);
150
+ const currentView = _chunk7WAGAQLTcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
151
+ const pending = _chunk7WAGAQLTcjs.signal.call(void 0, 0);
152
152
  let resolvedOnce = false;
153
153
  let epoch = 0;
154
- const hostRoot = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
154
+ const hostRoot = _chunk7WAGAQLTcjs.getCurrentRoot.call(void 0, );
155
155
  const toFallback = (err) => typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
156
156
  const switchView = (view) => {
157
157
  currentView(view);
@@ -163,42 +163,42 @@ function Suspense(props) {
163
163
  cleanup = void 0;
164
164
  }
165
165
  if (activeNodes.length) {
166
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, activeNodes);
166
+ _chunk7WAGAQLTcjs.removeNodes.call(void 0, activeNodes);
167
167
  activeNodes = [];
168
168
  }
169
169
  if (view == null || view === false) {
170
170
  return;
171
171
  }
172
- const root = _chunkPMF6MWEVcjs.createRootContext.call(void 0, hostRoot);
173
- const prev = _chunkPMF6MWEVcjs.pushRoot.call(void 0, root);
172
+ const root = _chunk7WAGAQLTcjs.createRootContext.call(void 0, hostRoot);
173
+ const prev = _chunk7WAGAQLTcjs.pushRoot.call(void 0, root);
174
174
  let nodes = [];
175
175
  try {
176
- const output = _chunkPMF6MWEVcjs.createElement.call(void 0, view);
177
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, output);
176
+ const output = _chunk7WAGAQLTcjs.createElement.call(void 0, view);
177
+ nodes = _chunk7WAGAQLTcjs.toNodeArray.call(void 0, output);
178
178
  const suspendedAttempt = nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
179
179
  if (suspendedAttempt) {
180
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
181
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
180
+ _chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
181
+ _chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
182
182
  return;
183
183
  }
184
184
  const parentNode = marker.parentNode;
185
185
  if (parentNode) {
186
- _chunkPMF6MWEVcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
186
+ _chunk7WAGAQLTcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
187
187
  }
188
188
  } catch (err) {
189
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
190
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
191
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
192
- if (!_chunkPMF6MWEVcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
189
+ _chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
190
+ _chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
191
+ _chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
192
+ if (!_chunk7WAGAQLTcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
193
193
  throw err;
194
194
  }
195
195
  return;
196
196
  }
197
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
198
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
197
+ _chunk7WAGAQLTcjs.popRoot.call(void 0, prev);
198
+ _chunk7WAGAQLTcjs.flushOnMount.call(void 0, root);
199
199
  cleanup = () => {
200
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
201
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, nodes);
200
+ _chunk7WAGAQLTcjs.destroyRoot.call(void 0, root);
201
+ _chunk7WAGAQLTcjs.removeNodes.call(void 0, nodes);
202
202
  };
203
203
  activeNodes = nodes;
204
204
  };
@@ -213,7 +213,7 @@ function Suspense(props) {
213
213
  _optionalChain([props, 'access', _7 => _7.onResolve, 'optionalCall', _8 => _8()]);
214
214
  }
215
215
  };
216
- _chunkPMF6MWEVcjs.registerSuspenseHandler.call(void 0, (token) => {
216
+ _chunk7WAGAQLTcjs.registerSuspenseHandler.call(void 0, (token) => {
217
217
  const tokenEpoch = epoch;
218
218
  pending(pending() + 1);
219
219
  switchView(toFallback());
@@ -238,7 +238,7 @@ function Suspense(props) {
238
238
  const newPending = Math.max(0, pending() - 1);
239
239
  pending(newPending);
240
240
  _optionalChain([props, 'access', _9 => _9.onReject, 'optionalCall', _10 => _10(err)]);
241
- if (!_chunkPMF6MWEVcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
241
+ if (!_chunk7WAGAQLTcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
242
242
  throw err;
243
243
  }
244
244
  }
@@ -247,14 +247,14 @@ function Suspense(props) {
247
247
  }
248
248
  return false;
249
249
  });
250
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
250
+ _chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
251
251
  renderView(currentView());
252
252
  });
253
253
  if (props.resetKeys !== void 0) {
254
254
  const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
255
255
  const getter = isGetter ? props.resetKeys : void 0;
256
256
  let prev = isGetter ? getter() : props.resetKeys;
257
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
257
+ _chunk7WAGAQLTcjs.createEffect.call(void 0, () => {
258
258
  const next = getter ? getter() : props.resetKeys;
259
259
  if (prev !== next) {
260
260
  prev = next;
@@ -291,5 +291,5 @@ function Suspense(props) {
291
291
 
292
292
 
293
293
 
294
- exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunkPMF6MWEVcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunkPMF6MWEVcjs.batch2; exports.createContext = _chunkGJTYOFMOcjs.createContext; exports.createEffect = _chunkPMF6MWEVcjs.createEffect; exports.createElement = _chunkPMF6MWEVcjs.createElement; exports.createMemo = _chunkPMF6MWEVcjs.createMemo; exports.createPortal = _chunkPMF6MWEVcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunkPMF6MWEVcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkGJTYOFMOcjs.hasContext; exports.mergeProps = _chunkPMF6MWEVcjs.mergeProps; exports.onCleanup = _chunkPMF6MWEVcjs.onCleanup; exports.onDestroy = _chunkPMF6MWEVcjs.onDestroy; exports.onMount = _chunkPMF6MWEVcjs.onMount; exports.prop = _chunkPMF6MWEVcjs.prop; exports.render = _chunkPMF6MWEVcjs.render; exports.startTransition = _chunkPMF6MWEVcjs.startTransition; exports.untrack = _chunkPMF6MWEVcjs.untrack2; exports.useContext = _chunkGJTYOFMOcjs.useContext; exports.useDeferredValue = _chunkPMF6MWEVcjs.useDeferredValue; exports.useTransition = _chunkPMF6MWEVcjs.useTransition;
294
+ exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunk7WAGAQLTcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunk7WAGAQLTcjs.batch2; exports.createContext = _chunkQ4EN6BXVcjs.createContext; exports.createEffect = _chunk7WAGAQLTcjs.createEffect; exports.createElement = _chunk7WAGAQLTcjs.createElement; exports.createMemo = _chunk7WAGAQLTcjs.createMemo; exports.createPortal = _chunk7WAGAQLTcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunk7WAGAQLTcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkQ4EN6BXVcjs.hasContext; exports.mergeProps = _chunk7WAGAQLTcjs.mergeProps; exports.onCleanup = _chunk7WAGAQLTcjs.onCleanup; exports.onDestroy = _chunk7WAGAQLTcjs.onDestroy; exports.onMount = _chunk7WAGAQLTcjs.onMount; exports.prop = _chunk7WAGAQLTcjs.prop; exports.render = _chunk7WAGAQLTcjs.render; exports.startTransition = _chunk7WAGAQLTcjs.startTransition; exports.untrack = _chunk7WAGAQLTcjs.untrack2; exports.useContext = _chunkQ4EN6BXVcjs.useContext; exports.useDeferredValue = _chunk7WAGAQLTcjs.useDeferredValue; exports.useTransition = _chunk7WAGAQLTcjs.useTransition;
295
295
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-CrOMYbLv.cjs';
1
+ export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-BfmSLuyp.cjs';
2
2
  import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-Auji1rz9.cjs';
3
3
  export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-Auji1rz9.cjs';
4
4
  export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-UXySaqI_.cjs';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-ES0Ag_Wd.js';
1
+ export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-BBi8Tkks.js';
2
2
  import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-Auji1rz9.js';
3
3
  export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-Auji1rz9.js';
4
4
  export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-B7UYnfzM.js';
package/dist/index.dev.js CHANGED
@@ -132,7 +132,7 @@ var currentRoot;
132
132
  var currentEffectCleanups;
133
133
  var globalErrorHandlers = /* @__PURE__ */ new WeakMap();
134
134
  var globalSuspenseHandlers = /* @__PURE__ */ new WeakMap();
135
- function createRootContext(parent = currentRoot) {
135
+ function createRootContext(parent) {
136
136
  return { parent, cleanups: [], destroyCallbacks: [] };
137
137
  }
138
138
  function pushRoot(root) {
@@ -208,8 +208,9 @@ function destroyRoot(root) {
208
208
  globalSuspenseHandlers.delete(root);
209
209
  }
210
210
  }
211
- function createRoot(fn) {
212
- const root = createRootContext();
211
+ function createRoot(fn, options) {
212
+ const parent = options?.inherit ? currentRoot : void 0;
213
+ const root = createRootContext(parent);
213
214
  const prev = pushRoot(root);
214
215
  let value;
215
216
  try {
@@ -1301,8 +1302,7 @@ function getPropAlias(prop2, tagName) {
1301
1302
  return a;
1302
1303
  }
1303
1304
  var $$EVENTS = "_$FICT_DELEGATE";
1304
- var delegatedEvents = isDev4 ? DelegatedEventNames : [];
1305
- var DelegatedEvents = new Set(delegatedEvents);
1305
+ var DelegatedEvents = new Set(DelegatedEventNames);
1306
1306
  var svgElements = isDev4 ? [
1307
1307
  "altGlyph",
1308
1308
  "altGlyphDef",
@@ -1907,7 +1907,8 @@ function bindEvent(el, eventName, handler, options) {
1907
1907
  if (handler == null) return () => {
1908
1908
  };
1909
1909
  const rootRef = getCurrentRoot();
1910
- if (isDev5 && DelegatedEvents.has(eventName) && !options) {
1910
+ const shouldDelegate = options == null && DelegatedEvents.has(eventName);
1911
+ if (shouldDelegate) {
1911
1912
  const key = `$$${eventName}`;
1912
1913
  delegateEvents([eventName]);
1913
1914
  const resolveHandler = isReactive(handler) ? handler : () => handler;
@@ -2026,17 +2027,27 @@ function __fictPopContext() {
2026
2027
  }
2027
2028
 
2028
2029
  // src/props.ts
2030
+ var PROP_GETTER_MARKER = Symbol.for("fict:prop-getter");
2029
2031
  var propGetters = /* @__PURE__ */ new WeakSet();
2030
2032
  var rawToProxy = /* @__PURE__ */ new WeakMap();
2031
2033
  var proxyToRaw = /* @__PURE__ */ new WeakMap();
2032
2034
  function __fictProp(getter) {
2033
2035
  if (typeof getter === "function" && getter.length === 0) {
2034
2036
  propGetters.add(getter);
2037
+ if (Object.isExtensible(getter)) {
2038
+ try {
2039
+ ;
2040
+ getter[PROP_GETTER_MARKER] = true;
2041
+ } catch {
2042
+ }
2043
+ }
2035
2044
  }
2036
2045
  return getter;
2037
2046
  }
2038
2047
  function isPropGetter(value) {
2039
- return typeof value === "function" && propGetters.has(value);
2048
+ if (typeof value !== "function") return false;
2049
+ const fn = value;
2050
+ return propGetters.has(fn) || fn[PROP_GETTER_MARKER] === true;
2040
2051
  }
2041
2052
  function createPropsProxy(props) {
2042
2053
  if (!props || typeof props !== "object") {
@@ -2150,11 +2161,21 @@ function mergeProps(...sources) {
2150
2161
  }
2151
2162
  });
2152
2163
  }
2153
- function prop(getter) {
2164
+ function prop(getter, options) {
2154
2165
  if (isPropGetter(getter)) {
2155
2166
  return getter;
2156
2167
  }
2157
- return __fictProp(createMemo(getter));
2168
+ const fn = getter;
2169
+ const unwrap = options?.unwrap !== false;
2170
+ return __fictProp(
2171
+ createMemo(() => {
2172
+ const value = fn();
2173
+ if (unwrap && isPropGetter(value)) {
2174
+ return value();
2175
+ }
2176
+ return value;
2177
+ })
2178
+ );
2158
2179
  }
2159
2180
 
2160
2181
  // src/dom.ts