@fictjs/runtime 0.2.1 → 0.2.3

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/advanced.cjs CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkZ5WRKD7Ycjs = require('./chunk-Z5WRKD7Y.cjs');
5
+ var _chunkW525IQWCcjs = require('./chunk-W525IQWC.cjs');
6
6
 
7
7
 
8
8
 
9
- var _chunk7EAEROZ5cjs = require('./chunk-7EAEROZ5.cjs');
9
+ var _chunk5YTFFAVUcjs = require('./chunk-5YTFFAVU.cjs');
10
10
 
11
11
 
12
12
 
@@ -23,13 +23,13 @@ var _chunk7EAEROZ5cjs = require('./chunk-7EAEROZ5.cjs');
23
23
 
24
24
 
25
25
 
26
- var _chunkMWI3USXBcjs = require('./chunk-MWI3USXB.cjs');
26
+ var _chunk2U6M3LKScjs = require('./chunk-2U6M3LKS.cjs');
27
27
 
28
28
  // src/versioned-signal.ts
29
29
  function createVersionedSignal(initialValue, options) {
30
30
  const equals = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.equals]), () => ( Object.is));
31
- const value = _chunkMWI3USXBcjs.signal.call(void 0, initialValue);
32
- const version = _chunkMWI3USXBcjs.signal.call(void 0, 0);
31
+ const value = _chunk2U6M3LKScjs.signal.call(void 0, initialValue);
32
+ const version = _chunk2U6M3LKScjs.signal.call(void 0, 0);
33
33
  const bumpVersion = () => {
34
34
  const next = version() + 1;
35
35
  version(next);
@@ -50,8 +50,8 @@ function createVersionedSignal(initialValue, options) {
50
50
  force: () => {
51
51
  bumpVersion();
52
52
  },
53
- peekVersion: () => _chunkMWI3USXBcjs.untrack.call(void 0, () => version()),
54
- peekValue: () => _chunkMWI3USXBcjs.untrack.call(void 0, () => value())
53
+ peekVersion: () => _chunk2U6M3LKScjs.untrack.call(void 0, () => version()),
54
+ peekValue: () => _chunk2U6M3LKScjs.untrack.call(void 0, () => value())
55
55
  };
56
56
  }
57
57
 
@@ -75,5 +75,5 @@ function createVersionedSignal(initialValue, options) {
75
75
 
76
76
 
77
77
 
78
- exports.createAttributeBinding = _chunkMWI3USXBcjs.createAttributeBinding; exports.createChildBinding = _chunkMWI3USXBcjs.createChildBinding; exports.createClassBinding = _chunkMWI3USXBcjs.createClassBinding; exports.createContext = _chunkZ5WRKD7Ycjs.createContext; exports.createRenderEffect = _chunkMWI3USXBcjs.createRenderEffect; exports.createScope = _chunk7EAEROZ5cjs.createScope; exports.createSelector = _chunkMWI3USXBcjs.createSelector; exports.createShow = _chunkMWI3USXBcjs.createShow; exports.createSignal = _chunkMWI3USXBcjs.signal; exports.createStyleBinding = _chunkMWI3USXBcjs.createStyleBinding; exports.createTextBinding = _chunkMWI3USXBcjs.createTextBinding; exports.createVersionedSignal = createVersionedSignal; exports.effectScope = _chunkMWI3USXBcjs.effectScope; exports.getDevtoolsHook = _chunkMWI3USXBcjs.getDevtoolsHook; exports.hasContext = _chunkZ5WRKD7Ycjs.hasContext; exports.isReactive = _chunkMWI3USXBcjs.isReactive; exports.runInScope = _chunk7EAEROZ5cjs.runInScope; exports.setCycleProtectionOptions = _chunkMWI3USXBcjs.setCycleProtectionOptions; exports.unwrap = _chunkMWI3USXBcjs.unwrap; exports.useContext = _chunkZ5WRKD7Ycjs.useContext;
78
+ exports.createAttributeBinding = _chunk2U6M3LKScjs.createAttributeBinding; exports.createChildBinding = _chunk2U6M3LKScjs.createChildBinding; exports.createClassBinding = _chunk2U6M3LKScjs.createClassBinding; exports.createContext = _chunkW525IQWCcjs.createContext; exports.createRenderEffect = _chunk2U6M3LKScjs.createRenderEffect; exports.createScope = _chunk5YTFFAVUcjs.createScope; exports.createSelector = _chunk2U6M3LKScjs.createSelector; exports.createShow = _chunk2U6M3LKScjs.createShow; exports.createSignal = _chunk2U6M3LKScjs.signal; exports.createStyleBinding = _chunk2U6M3LKScjs.createStyleBinding; exports.createTextBinding = _chunk2U6M3LKScjs.createTextBinding; exports.createVersionedSignal = createVersionedSignal; exports.effectScope = _chunk2U6M3LKScjs.effectScope; exports.getDevtoolsHook = _chunk2U6M3LKScjs.getDevtoolsHook; exports.hasContext = _chunkW525IQWCcjs.hasContext; exports.isReactive = _chunk2U6M3LKScjs.isReactive; exports.runInScope = _chunk5YTFFAVUcjs.runInScope; exports.setCycleProtectionOptions = _chunk2U6M3LKScjs.setCycleProtectionOptions; exports.unwrap = _chunk2U6M3LKScjs.unwrap; exports.useContext = _chunkW525IQWCcjs.useContext;
79
79
  //# sourceMappingURL=advanced.cjs.map
@@ -37,6 +37,8 @@ interface FictDevtoolsHook {
37
37
  declare function getDevtoolsHook(): FictDevtoolsHook | undefined;
38
38
 
39
39
  interface CycleProtectionOptions {
40
+ /** Enable cycle protection guards (defaults to dev-only) */
41
+ enabled?: boolean;
40
42
  maxFlushCyclesPerMicrotask?: number;
41
43
  maxEffectRunsPerFlush?: number;
42
44
  windowSize?: number;
@@ -37,6 +37,8 @@ interface FictDevtoolsHook {
37
37
  declare function getDevtoolsHook(): FictDevtoolsHook | undefined;
38
38
 
39
39
  interface CycleProtectionOptions {
40
+ /** Enable cycle protection guards (defaults to dev-only) */
41
+ enabled?: boolean;
40
42
  maxFlushCyclesPerMicrotask?: number;
41
43
  maxEffectRunsPerFlush?: number;
42
44
  windowSize?: number;
package/dist/advanced.js CHANGED
@@ -2,11 +2,11 @@ import {
2
2
  createContext,
3
3
  hasContext,
4
4
  useContext
5
- } from "./chunk-VVNMIER7.js";
5
+ } from "./chunk-3WD7QD5G.js";
6
6
  import {
7
7
  createScope,
8
8
  runInScope
9
- } from "./chunk-7TPCESQS.js";
9
+ } from "./chunk-UHXUEGQH.js";
10
10
  import {
11
11
  createAttributeBinding,
12
12
  createChildBinding,
@@ -23,7 +23,7 @@ import {
23
23
  signal,
24
24
  untrack,
25
25
  unwrap
26
- } from "./chunk-FOLRR3NZ.js";
26
+ } from "./chunk-YVDWXY44.js";
27
27
 
28
28
  // src/versioned-signal.ts
29
29
  function createVersionedSignal(initialValue, options) {
@@ -400,110 +400,117 @@ var endFlushGuard = () => {
400
400
  var enterRootGuard = () => true;
401
401
  var exitRootGuard = () => {
402
402
  };
403
- if (isDev2) {
404
- const defaultOptions = {
405
- maxFlushCyclesPerMicrotask: 1e4,
406
- maxEffectRunsPerFlush: 2e4,
407
- windowSize: 5,
408
- highUsageRatio: 0.8,
409
- maxRootReentrantDepth: 10,
410
- enableWindowWarning: true,
411
- devMode: false
412
- };
413
- let options = {
414
- ...defaultOptions
415
- };
416
- let effectRunsThisFlush = 0;
417
- let windowUsage = [];
418
- let rootDepth = /* @__PURE__ */ new WeakMap();
419
- let flushWarned = false;
420
- let rootWarned = false;
421
- let windowWarned = false;
422
- setCycleProtectionOptions = exports.setCycleProtectionOptions = (opts) => {
423
- options = { ...options, ...opts };
424
- };
425
- resetCycleProtectionStateForTests = () => {
426
- options = { ...defaultOptions };
427
- effectRunsThisFlush = 0;
428
- windowUsage = [];
429
- rootDepth = /* @__PURE__ */ new WeakMap();
430
- flushWarned = false;
431
- rootWarned = false;
432
- windowWarned = false;
433
- };
434
- beginFlushGuard = () => {
435
- effectRunsThisFlush = 0;
436
- flushWarned = false;
437
- windowWarned = false;
438
- };
439
- beforeEffectRunGuard = () => {
440
- const next = ++effectRunsThisFlush;
441
- if (next > options.maxFlushCyclesPerMicrotask || next > options.maxEffectRunsPerFlush) {
442
- const message = `[fict] cycle protection triggered: flush-budget-exceeded`;
443
- if (options.devMode) {
444
- throw new Error(message);
445
- }
446
- if (!flushWarned) {
447
- flushWarned = true;
448
- console.warn(message, { effectRuns: next });
449
- }
450
- return false;
451
- }
452
- return true;
453
- };
454
- endFlushGuard = () => {
455
- recordWindowUsage(effectRunsThisFlush, options.maxFlushCyclesPerMicrotask);
456
- effectRunsThisFlush = 0;
457
- };
458
- enterRootGuard = (root) => {
459
- const depth = (_nullishCoalesce(rootDepth.get(root), () => ( 0))) + 1;
460
- if (depth > options.maxRootReentrantDepth) {
461
- const message = `[fict] cycle protection triggered: root-reentry`;
462
- if (options.devMode) {
463
- throw new Error(message);
464
- }
465
- if (!rootWarned) {
466
- rootWarned = true;
467
- console.warn(message, { depth });
468
- }
469
- return false;
470
- }
471
- rootDepth.set(root, depth);
472
- return true;
473
- };
474
- exitRootGuard = (root) => {
475
- const depth = rootDepth.get(root);
476
- if (depth === void 0) return;
477
- if (depth <= 1) {
478
- rootDepth.delete(root);
479
- } else {
480
- rootDepth.set(root, depth - 1);
403
+ var defaultOptions = {
404
+ enabled: isDev2,
405
+ maxFlushCyclesPerMicrotask: 1e4,
406
+ maxEffectRunsPerFlush: 2e4,
407
+ windowSize: 5,
408
+ highUsageRatio: 0.8,
409
+ maxRootReentrantDepth: 10,
410
+ enableWindowWarning: true,
411
+ devMode: false
412
+ };
413
+ var enabled = defaultOptions.enabled;
414
+ var options = {
415
+ ...defaultOptions
416
+ };
417
+ var effectRunsThisFlush = 0;
418
+ var windowUsage = [];
419
+ var rootDepth = /* @__PURE__ */ new WeakMap();
420
+ var flushWarned = false;
421
+ var rootWarned = false;
422
+ var windowWarned = false;
423
+ setCycleProtectionOptions = exports.setCycleProtectionOptions = (opts) => {
424
+ if (typeof opts.enabled === "boolean") {
425
+ enabled = opts.enabled;
426
+ }
427
+ options = { ...options, ...opts };
428
+ };
429
+ resetCycleProtectionStateForTests = () => {
430
+ options = { ...defaultOptions };
431
+ enabled = defaultOptions.enabled;
432
+ effectRunsThisFlush = 0;
433
+ windowUsage = [];
434
+ rootDepth = /* @__PURE__ */ new WeakMap();
435
+ flushWarned = false;
436
+ rootWarned = false;
437
+ windowWarned = false;
438
+ };
439
+ beginFlushGuard = () => {
440
+ if (!enabled) return;
441
+ effectRunsThisFlush = 0;
442
+ flushWarned = false;
443
+ windowWarned = false;
444
+ };
445
+ beforeEffectRunGuard = () => {
446
+ if (!enabled) return true;
447
+ const next = ++effectRunsThisFlush;
448
+ if (next > options.maxFlushCyclesPerMicrotask || next > options.maxEffectRunsPerFlush) {
449
+ const message = `[fict] cycle protection triggered: flush-budget-exceeded`;
450
+ if (options.devMode) {
451
+ throw new Error(message);
452
+ }
453
+ if (!flushWarned) {
454
+ flushWarned = true;
455
+ console.warn(message, { effectRuns: next });
481
456
  }
482
- };
483
- const recordWindowUsage = (used, budget) => {
484
- if (!options.enableWindowWarning) return;
485
- const entry = { used, budget };
486
- windowUsage.push(entry);
487
- if (windowUsage.length > options.windowSize) {
488
- windowUsage.shift();
489
- }
490
- if (windowWarned) return;
491
- if (windowUsage.length >= options.windowSize && windowUsage.every(
492
- (item) => item.budget > 0 && item.used / item.budget >= options.highUsageRatio
493
- )) {
494
- windowWarned = true;
495
- reportCycle("high-usage-window", {
496
- windowSize: options.windowSize,
497
- ratio: options.highUsageRatio
498
- });
457
+ return false;
458
+ }
459
+ return true;
460
+ };
461
+ endFlushGuard = () => {
462
+ if (!enabled) return;
463
+ recordWindowUsage(effectRunsThisFlush, options.maxFlushCyclesPerMicrotask);
464
+ effectRunsThisFlush = 0;
465
+ };
466
+ enterRootGuard = (root) => {
467
+ if (!enabled) return true;
468
+ const depth = (_nullishCoalesce(rootDepth.get(root), () => ( 0))) + 1;
469
+ if (depth > options.maxRootReentrantDepth) {
470
+ const message = `[fict] cycle protection triggered: root-reentry`;
471
+ if (options.devMode) {
472
+ throw new Error(message);
473
+ }
474
+ if (!rootWarned) {
475
+ rootWarned = true;
476
+ console.warn(message, { depth });
499
477
  }
500
- };
501
- const reportCycle = (reason, detail = void 0) => {
502
- const hook = getDevtoolsHook();
503
- _optionalChain([hook, 'optionalAccess', _6 => _6.cycleDetected, 'optionalCall', _7 => _7(detail ? { reason, detail } : { reason })]);
504
- console.warn(`[fict] cycle protection triggered: ${reason}`, _nullishCoalesce(detail, () => ( "")));
505
- };
506
- }
478
+ return false;
479
+ }
480
+ rootDepth.set(root, depth);
481
+ return true;
482
+ };
483
+ exitRootGuard = (root) => {
484
+ if (!enabled) return;
485
+ const depth = rootDepth.get(root);
486
+ if (depth === void 0) return;
487
+ if (depth <= 1) {
488
+ rootDepth.delete(root);
489
+ } else {
490
+ rootDepth.set(root, depth - 1);
491
+ }
492
+ };
493
+ var recordWindowUsage = (used, budget) => {
494
+ if (!options.enableWindowWarning) return;
495
+ const entry = { used, budget };
496
+ windowUsage.push(entry);
497
+ if (windowUsage.length > options.windowSize) {
498
+ windowUsage.shift();
499
+ }
500
+ if (windowWarned) return;
501
+ if (windowUsage.length >= options.windowSize && windowUsage.every((item) => item.budget > 0 && item.used / item.budget >= options.highUsageRatio)) {
502
+ windowWarned = true;
503
+ reportCycle("high-usage-window", {
504
+ windowSize: options.windowSize,
505
+ ratio: options.highUsageRatio
506
+ });
507
+ }
508
+ };
509
+ var reportCycle = (reason, detail = void 0) => {
510
+ const hook = getDevtoolsHook();
511
+ _optionalChain([hook, 'optionalAccess', _6 => _6.cycleDetected, 'optionalCall', _7 => _7(detail ? { reason, detail } : { reason })]);
512
+ console.warn(`[fict] cycle protection triggered: ${reason}`, _nullishCoalesce(detail, () => ( "")));
513
+ };
507
514
 
508
515
  // src/lifecycle.ts
509
516
  var isDev3 = true ? false : typeof process === "undefined" || _optionalChain([process, 'access', _8 => _8.env, 'optionalAccess', _9 => _9.NODE_ENV]) !== "production";
@@ -587,8 +594,8 @@ function destroyRoot(root) {
587
594
  globalSuspenseHandlers.delete(root);
588
595
  }
589
596
  }
590
- function createRoot(fn, options) {
591
- const parent = _optionalChain([options, 'optionalAccess', _10 => _10.inherit]) ? currentRoot : void 0;
597
+ function createRoot(fn, options2) {
598
+ const parent = _optionalChain([options2, 'optionalAccess', _10 => _10.inherit]) ? currentRoot : void 0;
592
599
  const root = createRootContext(parent);
593
600
  const prev = pushRoot(root);
594
601
  let value;
@@ -2275,11 +2282,11 @@ function addEventListener(node, name, handler, delegate) {
2275
2282
  node.addEventListener(name, handler);
2276
2283
  }
2277
2284
  }
2278
- function bindEvent(el, eventName, handler, options) {
2285
+ function bindEvent(el, eventName, handler, options2) {
2279
2286
  if (handler == null) return () => {
2280
2287
  };
2281
2288
  const rootRef = getCurrentRoot();
2282
- const shouldDelegate = options == null && DelegatedEvents.has(eventName);
2289
+ const shouldDelegate = options2 == null && DelegatedEvents.has(eventName);
2283
2290
  if (shouldDelegate) {
2284
2291
  const key = `$$${eventName}`;
2285
2292
  delegateEvents([eventName]);
@@ -2310,8 +2317,8 @@ function bindEvent(el, eventName, handler, options) {
2310
2317
  throw err;
2311
2318
  }
2312
2319
  };
2313
- el.addEventListener(eventName, wrapped, options);
2314
- const cleanup = () => el.removeEventListener(eventName, wrapped, options);
2320
+ el.addEventListener(eventName, wrapped, options2);
2321
+ const cleanup = () => el.removeEventListener(eventName, wrapped, options2);
2315
2322
  registerRootCleanup(cleanup);
2316
2323
  return cleanup;
2317
2324
  }
@@ -2875,12 +2882,12 @@ function mergeProps(...sources) {
2875
2882
  }
2876
2883
  });
2877
2884
  }
2878
- function prop(getter, options) {
2885
+ function prop(getter, options2) {
2879
2886
  if (isPropGetter(getter)) {
2880
2887
  return getter;
2881
2888
  }
2882
2889
  const fn = getter;
2883
- const unwrap2 = _optionalChain([options, 'optionalAccess', _35 => _35.unwrap]) !== false;
2890
+ const unwrap2 = _optionalChain([options2, 'optionalAccess', _35 => _35.unwrap]) !== false;
2884
2891
  return __fictProp(
2885
2892
  createMemo(() => {
2886
2893
  const value = fn();
@@ -3282,8 +3289,10 @@ var setProperty = (el, key, value) => {
3282
3289
  el[key] = value;
3283
3290
  };
3284
3291
  var setInnerHTML = (el, _key, value) => {
3285
- ;
3286
- el.innerHTML = value == null ? "" : String(value);
3292
+ const next = value == null ? "" : String(value);
3293
+ const node = el;
3294
+ if (node.innerHTML === next) return;
3295
+ node.innerHTML = next;
3287
3296
  };
3288
3297
  var setBoolAttribute = (el, key, value) => {
3289
3298
  if (value) {
@@ -3393,4 +3402,4 @@ function eventNameFromProp(key) {
3393
3402
 
3394
3403
 
3395
3404
  exports.BooleanAttributes = BooleanAttributes; exports.Properties = Properties; exports.ChildProperties = ChildProperties; exports.Aliases = Aliases; exports.getPropAlias = getPropAlias; exports.DelegatedEvents = DelegatedEvents; exports.SVGElements = SVGElements; exports.SVGNamespace = SVGNamespace; exports.UnitlessStyles = UnitlessStyles; exports.getDevtoolsHook = getDevtoolsHook; exports.setCycleProtectionOptions = setCycleProtectionOptions; exports.createRootContext = createRootContext; exports.pushRoot = pushRoot; exports.getCurrentRoot = getCurrentRoot; exports.popRoot = popRoot; exports.onMount = onMount; exports.onDestroy = onDestroy; exports.onCleanup = onCleanup; exports.flushOnMount = flushOnMount; exports.registerRootCleanup = registerRootCleanup; exports.destroyRoot = destroyRoot; exports.createRoot = createRoot; exports.registerErrorHandler = registerErrorHandler; exports.registerSuspenseHandler = registerSuspenseHandler; exports.handleError = handleError; exports.flush = flush; exports.signal = signal; exports.effectScope = effectScope; exports.batch = batch; exports.setActiveSub = setActiveSub; exports.untrack = untrack; exports.createSelector = createSelector; exports.createEffect = createEffect; exports.createRenderEffect = createRenderEffect; exports.Fragment = Fragment; exports.toNodeArray = toNodeArray; exports.insertNodesBefore = insertNodesBefore; exports.removeNodes = removeNodes; exports.startTransition = startTransition; exports.useTransition = useTransition; exports.useDeferredValue = useDeferredValue; exports.batch2 = batch2; exports.untrack2 = untrack2; exports.isReactive = isReactive; exports.unwrap = unwrap; exports.callEventHandler = callEventHandler; exports.createTextBinding = createTextBinding; exports.bindText = bindText; exports.createAttributeBinding = createAttributeBinding; exports.bindAttribute = bindAttribute; exports.bindProperty = bindProperty; exports.createStyleBinding = createStyleBinding; exports.bindStyle = bindStyle; exports.createClassBinding = createClassBinding; exports.bindClass = bindClass; exports.classList = classList; exports.insert = insert; exports.createChildBinding = createChildBinding; exports.delegateEvents = delegateEvents; exports.clearDelegatedEvents = clearDelegatedEvents; exports.addEventListener = addEventListener; exports.bindEvent = bindEvent; exports.bindRef = bindRef; exports.spread = spread; exports.assign = assign; exports.createConditional = createConditional; exports.createShow = createShow; exports.createPortal = createPortal; exports.createMemo = createMemo; exports.__fictUseContext = __fictUseContext; exports.__fictPushContext = __fictPushContext; exports.__fictPopContext = __fictPopContext; exports.__fictResetContext = __fictResetContext; exports.__fictUseSignal = __fictUseSignal; exports.__fictUseMemo = __fictUseMemo; exports.__fictUseEffect = __fictUseEffect; exports.__fictRender = __fictRender; exports.__fictProp = __fictProp; exports.createPropsProxy = createPropsProxy; exports.__fictPropsRest = __fictPropsRest; exports.mergeProps = mergeProps; exports.prop = prop; exports.render = render; exports.createElement = createElement; exports.template = template;
3396
- //# sourceMappingURL=chunk-MWI3USXB.cjs.map
3405
+ //# sourceMappingURL=chunk-2U6M3LKS.cjs.map