@ghostry/fabricator 0.0.2 → 0.0.4

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 (44) hide show
  1. package/README.md +18 -6
  2. package/dist/esm/Adapter/Core.js +3 -3
  3. package/dist/esm/Enumeration/Enumerate.js +22 -18
  4. package/dist/esm/Error/index.js +8 -8
  5. package/dist/esm/Fabricator/Constructor.js +22 -23
  6. package/dist/esm/Harnessing/Core.js +30 -0
  7. package/dist/esm/Harnessing/Salt.js +12 -0
  8. package/dist/esm/Harnessing/Types.js +1 -0
  9. package/dist/esm/Instance/Core.js +65 -38
  10. package/dist/esm/Instance/Stack/Async.js +10 -2
  11. package/dist/esm/Instance/Stack/Sync.js +2 -1
  12. package/dist/esm/Instance/Stack/Visible.js +13 -0
  13. package/dist/esm/Primitive/recursive/Fabricator.js +1 -1
  14. package/dist/esm/Random/index.js +25 -80
  15. package/dist/esm/adapting.js +2 -0
  16. package/dist/esm/harnessing.js +1 -0
  17. package/dist/esm/index.js +1 -2
  18. package/dist/esm/internal.js +1 -2
  19. package/dist/types/Adapter/Core.d.ts +1 -1
  20. package/dist/types/Adapter/Types.d.ts +1 -1
  21. package/dist/types/Enumeration/Enumerate.d.ts +23 -21
  22. package/dist/types/Error/index.d.ts +15 -19
  23. package/dist/types/Fabricator/Constructor.d.ts +14 -11
  24. package/dist/types/Fabricator/Types.d.ts +15 -14
  25. package/dist/types/Harnessing/Core.d.ts +43 -0
  26. package/dist/types/Harnessing/Salt.d.ts +31 -0
  27. package/dist/types/Harnessing/Types.d.ts +79 -0
  28. package/dist/types/Instance/Core.d.ts +31 -37
  29. package/dist/types/Instance/Stack/Async.d.ts +7 -0
  30. package/dist/types/Instance/Stack/Sync.d.ts +5 -3
  31. package/dist/types/Instance/Stack/Visible.d.ts +22 -0
  32. package/dist/types/Instance/Types.d.ts +202 -58
  33. package/dist/types/Primitive/opaque/Registry.d.ts +1 -1
  34. package/dist/types/Primitive/recursive/Fabricator.d.ts +8 -9
  35. package/dist/types/Random/Types.d.ts +103 -221
  36. package/dist/types/Random/index.d.ts +33 -51
  37. package/dist/types/Types.d.ts +3 -3
  38. package/dist/types/adapting.d.ts +32 -0
  39. package/dist/types/harnessing.d.ts +30 -0
  40. package/dist/types/index.d.ts +51 -77
  41. package/dist/types/internal.d.ts +5 -23
  42. package/package.json +23 -3
  43. package/dist/esm/Random/CallSite.js +0 -70
  44. package/dist/types/Random/CallSite.d.ts +0 -78
package/README.md CHANGED
@@ -1,6 +1,20 @@
1
- # fabricator
1
+ <div align="center">
2
2
 
3
- Fabricate typed data from composable schemas.
3
+ <img src="https://docs.ghostry.dev/fabricator/logo.png" alt="fabricator" width="96" height="96">
4
+
5
+ # @ghostry/fabricator
6
+
7
+ **Fabricate typed data from composable schemas.**
8
+
9
+ [![npm](https://img.shields.io/badge/npm-ffffff.svg?style=for-the-badge&color=000000&logo=npm&logoColor=CB3837)](https://www.npmjs.com/package/@ghostry/fabricator)
10
+ [![npmx](https://img.shields.io/badge/npmx-ffffff.svg?style=for-the-badge&color=000000&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTMiIGhlaWdodD0iMTUzIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxNTMgMTUzIj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNi43MDQgOS45ODI3KSI+CiAgICA8cGF0aCBkPSJtMC45MzQ3NiA5Ny4yMDVoMjQuMDgxdjIzLjY5M2gtMjQuMDgxeiIgZmlsbD0iI2ZmZiI+PC9wYXRoPgogICAgPHBhdGggZD0ibTEwMy4xMi05LjIzMDctMy42MjExIDEwLjI0Ni00Ni4zMDkgMTMxLTMuNjIxMSAxMC4yNDZoMTUuNTM3bDMuNjIxMS0xMC4yNDYgMTEuNzE3LTMzLjE0OCAzOC4yMTEtMTA4LjF6IiBmaWxsPSIjNTFjOGZjIj48L3BhdGg+CiAgPC9nPgo8L3N2Zz4K&logoColor=51C8FC)](https://npmx.dev/package/@ghostry/fabricator)
11
+ [![jsr](https://img.shields.io/badge/jsr-ffffff?style=for-the-badge&color=000000&logo=jsr&logoColor=F7DF1E)](https://jsr.io/@ghostry/fabricator)
12
+ [![github](https://img.shields.io/badge/github-ffffff?style=for-the-badge&color=000000&logo=github&logoColor=ffffff)](https://github.com/ghostry-dev/fabricator)
13
+ [![typescript](https://img.shields.io/badge/typescript-ffffff?style=for-the-badge&color=000000&logo=typescript&logoColor=3178C6)](#)
14
+ [![bun](https://img.shields.io/badge/bun-ffffff?style=for-the-badge&color=000000&logo=bun&logoColor=FBF0DF)](#)
15
+ [![node](https://img.shields.io/badge/node-ffffff?style=for-the-badge&color=000000&logo=nodedotjs&logoColor=5FA04E)](#)
16
+
17
+ </div>
4
18
 
5
19
  ## Install
6
20
 
@@ -8,14 +22,12 @@ Fabricate typed data from composable schemas.
8
22
  npm install @ghostry/fabricator
9
23
  ```
10
24
 
11
- Also available via `bun add @ghostry/fabricator` or `bunx jsr add @ghostry/fabricator`.
12
-
13
25
  ## Example
14
26
 
15
27
  ```ts
16
28
  import { initialize } from "@ghostry/fabricator";
17
29
 
18
- const { T, Fabricator } = initialize({ seed: "1234" });
30
+ const { T, Fabricator } = initialize();
19
31
 
20
32
  const ProductSchema = T.object({
21
33
  name: T.string.whereby({ length: { min: 1, max: 25 } }),
@@ -38,4 +50,4 @@ const item = Product.fabricate();
38
50
  const widget = Product.fabricate({ name: "Widget", inStock: true });
39
51
  ```
40
52
 
41
- `seed: "1234"` is an optional mixer; `clock` (the wall-clock instant of this call, by default) is the run's entropy. Pass the same seed and clock to replay. See the [docs site](https://docs.ghostry.dev/fabricator/) for the full guide: the mental model behind Schemas and Fabricators, composing and overriding schemas, custom types, distributions, and the [TypeBox adapter](https://www.npmjs.com/package/@ghostry/fabricator-adapter-typebox-v0).
53
+ `initialize()` takes no required configuration. Its `clock` (by default, the wall-clock instant of the call) is the run's entropy, so every run differs, and passing that one number back as `clock` replays the run exactly. See the [docs site](https://docs.ghostry.dev/fabricator/) for the full guide: the mental model behind Schemas and Fabricators, composing and overriding schemas, custom types, distributions, and the [TypeBox adapter](https://www.npmjs.com/package/@ghostry/fabricator-adapter-typebox-v0).
@@ -38,10 +38,10 @@ function Core_layer(key, adaptation, prior) {
38
38
  [key]: prior
39
39
  }));
40
40
  }
41
- function drive(adapter, schema, context) {
41
+ function walk(adapter, schema, context) {
42
42
  var _schema_Adaptation;
43
43
  const adaptation = null == (_schema_Adaptation = schema[Adaptation]) ? void 0 : _schema_Adaptation[adapter.key];
44
44
  if (adaptation) return adaptation(schema);
45
- return adapter.convert(schema, (child, childContext)=>drive(adapter, child, childContext), context);
45
+ return adapter.convert(schema, (child, childContext)=>walk(adapter, child, childContext), context);
46
46
  }
47
- export { drive, mergeAdaptations, withAdaptations };
47
+ export { mergeAdaptations, walk, withAdaptations };
@@ -1,14 +1,15 @@
1
1
  import { shuffle } from "../Distribution/index.js";
2
2
  import { FabricatorError } from "../Error/index.js";
3
3
  import { Constructor } from "../Fabricator/Constructor.js";
4
+ import { toInnermostFrame } from "../Instance/Stack/Visible.js";
4
5
  import { toStreamFromTrace } from "../Random/index.js";
5
6
  import { plan, resolve } from "./Plan.js";
6
- function enumerables(source, limits, stack) {
7
- const Fabricator = Constructor(source, stack);
7
+ function enumerables(source, limits, stack, ancestry) {
8
+ const Fabricator = Constructor(source, stack, ancestry);
8
9
  function effectiveSource() {
9
10
  var _ref;
10
- var _stack_current;
11
- return null != (_ref = null == (_stack_current = stack.current()) ? void 0 : _stack_current.source) ? _ref : source;
11
+ var _toInnermostFrame;
12
+ return null != (_ref = null == (_toInnermostFrame = toInnermostFrame(stack, ancestry)) ? void 0 : _toInnermostFrame.source) ? _ref : source;
12
13
  }
13
14
  function iterable(rebuild) {
14
15
  return {
@@ -34,19 +35,21 @@ function enumerables(source, limits, stack) {
34
35
  };
35
36
  }
36
37
  function combinatorial(schema) {
37
- const combinatorialSeed = [
38
- ...effectiveSource().seed,
38
+ const combinatorialSalt = [
39
+ ...effectiveSource().salt,
39
40
  "combinatorial"
40
41
  ];
41
42
  const probe = plan(new Fabricator(schema, {
42
- seed: combinatorialSeed
43
+ salt: combinatorialSalt,
44
+ ordinal: null
43
45
  }), {
44
46
  strategy: "product"
45
47
  });
46
48
  if (probe.width > BigInt(limits.combinatorial)) throw new FabricatorError.CombinatorialLimitExceededError(probe.width, limits.combinatorial);
47
49
  return iterable(()=>{
48
50
  const built = new Fabricator(schema, {
49
- seed: combinatorialSeed
51
+ salt: combinatorialSalt,
52
+ ordinal: null
50
53
  });
51
54
  return {
52
55
  built,
@@ -58,24 +61,25 @@ function enumerables(source, limits, stack) {
58
61
  }
59
62
  function coverage(schema) {
60
63
  const base = effectiveSource();
61
- const coverageSeed = [
62
- ...base.seed,
64
+ const coverageSalt = [
65
+ ...base.salt,
63
66
  "coverage"
64
67
  ];
65
- const orderSeed = [
66
- ...base.seed,
68
+ const orderSalt = [
69
+ ...base.salt,
67
70
  "coverage",
68
71
  "order"
69
72
  ];
70
73
  return iterable(()=>{
71
74
  const built = new Fabricator(schema, {
72
- seed: coverageSeed
75
+ salt: coverageSalt,
76
+ ordinal: null
73
77
  });
74
78
  return {
75
79
  built,
76
80
  axis: plan(built, {
77
81
  strategy: "cycle",
78
- orderer: orderer(base, orderSeed)
82
+ orderer: orderer(base, orderSalt)
79
83
  })
80
84
  };
81
85
  });
@@ -85,11 +89,11 @@ function enumerables(source, limits, stack) {
85
89
  coverage
86
90
  };
87
91
  }
88
- function orderer(source, seed) {
89
- const forked = source.fork(seed);
90
- const root = forked.toRoot("unattributed");
92
+ function orderer(source, salt) {
93
+ const forked = source.fork(salt);
94
+ const trace = forked.toConstructionTrace();
91
95
  const stream = toStreamFromTrace(forked.algorithm, {
92
- ...root,
96
+ ...trace,
93
97
  path: [],
94
98
  kind: "order"
95
99
  });
@@ -31,14 +31,6 @@ class Error_FabricatorError extends Error {
31
31
  }
32
32
  }
33
33
  FabricatorError.InvalidCombinatorialLimitError = InvalidCombinatorialLimitError;
34
- class InvalidAttributionRootError extends FabricatorError {
35
- constructor(root){
36
- super(), _define_property(this, "root", void 0), this.root = root;
37
- this.name = "InvalidAttributionRootError";
38
- this.message = `initialize({ attribution: { kind: "rooted", root } }) requires an absolute path or a "file://" URL; received "${root}".`;
39
- }
40
- }
41
- FabricatorError.InvalidAttributionRootError = InvalidAttributionRootError;
42
34
  class DetachedSelfError extends FabricatorError {
43
35
  constructor(during){
44
36
  super(), _define_property(this, "during", void 0), this.during = during;
@@ -205,5 +197,13 @@ class Error_FabricatorError extends Error {
205
197
  }
206
198
  }
207
199
  FabricatorError.SynchronousStackError = SynchronousStackError;
200
+ class HarnessingProviderError extends FabricatorError {
201
+ constructor(){
202
+ super();
203
+ this.name = "HarnessingProviderError";
204
+ this.message = "The `fabricator` provider was called outside its integration's `around`, so there is no per-test scope to provide. A composer must run each integration's providers inside that integration's `around` frame, as `@ghostry/harness` does.";
205
+ }
206
+ }
207
+ FabricatorError.HarnessingProviderError = HarnessingProviderError;
208
208
  })(Error_FabricatorError || (Error_FabricatorError = {}));
209
209
  export { Error_FabricatorError as FabricatorError };
@@ -1,10 +1,11 @@
1
1
  import { FabricatorError } from "../Error/index.js";
2
+ import { toInnermostFrame } from "../Instance/Stack/Visible.js";
2
3
  import { Primitive } from "../Primitive/index.js";
3
- import { isLayered, normalizeSeed } from "../Random/index.js";
4
+ import { isLayered, normalizeSalt } from "../Random/index.js";
4
5
  import { toSchema } from "../Schema/Core.js";
5
6
  import { Adaptation, Fixed, Kind, Layer, Meta } from "../Types.js";
6
7
  import { inline } from "../Utility/Core.js";
7
- function Constructor(source, stack) {
8
+ function Constructor(source, stack, ancestry) {
8
9
  function make(schema, path, context) {
9
10
  schema = toSchema(schema);
10
11
  const kind = schema[Kind];
@@ -280,7 +281,7 @@ function Constructor(source, stack) {
280
281
  function construct(schema, options = {}) {
281
282
  var _options_path;
282
283
  if ("string" == typeof options.kind && options.kind !== schema[Kind]) throw new FabricatorError.TraceKindMismatchError(schema[Kind], options.kind);
283
- const context = toConstructionContext(source, options, stack);
284
+ const context = toConstructionContext(source, options, stack, ancestry);
284
285
  const made = make(schema, null != (_options_path = options.path) ? _options_path : [], context);
285
286
  const adaptations = schema[Adaptation];
286
287
  return adaptations ? {
@@ -290,39 +291,37 @@ function Constructor(source, stack) {
290
291
  }
291
292
  return construct;
292
293
  }
293
- function toConstructionContext(source, options, stack) {
294
- const { source: rooted, root: construction } = resolveScope(source, options, stack);
294
+ function toConstructionContext(source, options, stack, ancestry) {
295
+ const { source: resolved, trace } = resolveScope(source, options, stack, ancestry);
295
296
  return {
296
297
  toTrace: (path, kind)=>({
297
- ...construction,
298
+ ...trace,
298
299
  path,
299
300
  kind
300
301
  }),
301
- algorithm: rooted.algorithm
302
+ algorithm: resolved.algorithm
302
303
  };
303
304
  }
304
- function resolveScope(source, options, stack) {
305
+ function resolveScope(source, options, stack, ancestry) {
305
306
  var _ref;
306
- const frame = stack.current();
307
- const base = null != (_ref = null == frame ? void 0 : frame.source) ? _ref : source;
307
+ var _toInnermostFrame;
308
+ const base = null != (_ref = null == (_toInnermostFrame = toInnermostFrame(stack, ancestry)) ? void 0 : _toInnermostFrame.source) ? _ref : source;
309
+ const salt = inline(()=>{
310
+ if (!options.salt) return;
311
+ if (isLayered(options.salt)) return [
312
+ ...base.salt,
313
+ ...normalizeSalt(options.salt[Layer])
314
+ ];
315
+ return normalizeSalt(options.salt);
316
+ });
308
317
  const pins = {
318
+ salt,
309
319
  clock: options.clock,
310
- root: options.root,
311
- file: options.file,
312
320
  ordinal: options.ordinal
313
321
  };
314
- if (!options.seed) return {
315
- source: base,
316
- root: base.toRoot("attributed", pins)
317
- };
318
- const seed = isLayered(options.seed) ? [
319
- ...base.seed,
320
- ...normalizeSeed(options.seed[Layer])
321
- ] : options.seed;
322
- const forked = base.fork(seed);
323
322
  return {
324
- source: forked,
325
- root: forked.toRoot("unattributed", pins)
323
+ source: base,
324
+ trace: base.toConstructionTrace(pins)
326
325
  };
327
326
  }
328
327
  export { Constructor };
@@ -0,0 +1,30 @@
1
+ import { FabricatorError } from "../Error/index.js";
2
+ import { layer as index_js_layer } from "../Random/index.js";
3
+ import { saltFor } from "./Salt.js";
4
+ function integration(instance) {
5
+ let scope;
6
+ return {
7
+ name: "@ghostry/fabricator",
8
+ provides: {
9
+ fabricator: ()=>{
10
+ if (void 0 === scope) throw new FabricatorError.HarnessingProviderError();
11
+ return scope;
12
+ }
13
+ },
14
+ around (identity, body) {
15
+ const salt = index_js_layer(saltFor(identity));
16
+ return instance.wrap({
17
+ salt
18
+ }, (entered)=>{
19
+ const previous = scope;
20
+ scope = entered;
21
+ try {
22
+ return body();
23
+ } finally{
24
+ scope = previous;
25
+ }
26
+ });
27
+ }
28
+ };
29
+ }
30
+ export { integration };
@@ -0,0 +1,12 @@
1
+ function saltFor(identity) {
2
+ const salt = [
3
+ identity.kind,
4
+ ...identity.path,
5
+ identity.name
6
+ ];
7
+ return "number" == typeof identity.row ? [
8
+ ...salt,
9
+ String(identity.row)
10
+ ] : salt;
11
+ }
12
+ export { saltFor };
@@ -0,0 +1 @@
1
+ export { };
@@ -1,10 +1,11 @@
1
1
  import { enumerables } from "../Enumeration/Enumerate.js";
2
2
  import { FabricatorError } from "../Error/index.js";
3
3
  import { Constructor } from "../Fabricator/Constructor.js";
4
- import { defaultAlgorithm, deriveClock, isLayered, normalizeSeed, resolveAttribution, toRandomSource } from "../Random/index.js";
4
+ import { defaultAlgorithm, deriveClock, isLayered, normalizeSalt, toRandomSource } from "../Random/index.js";
5
5
  import { registry } from "../Schema/Registry.js";
6
6
  import { Layer } from "../Types.js";
7
7
  import { inline, isThenable, noop } from "../Utility/Core.js";
8
+ import { toInnermostFrame } from "./Stack/Visible.js";
8
9
  const DEFAULT_COMBINATORIAL_LIMIT = 1024;
9
10
  function resolveCombinatorialLimit(limit) {
10
11
  if (void 0 === limit) return DEFAULT_COMBINATORIAL_LIMIT;
@@ -12,57 +13,72 @@ function resolveCombinatorialLimit(limit) {
12
13
  return limit;
13
14
  }
14
15
  function resolveClock(config) {
15
- return "number" == typeof config.clock ? config.clock : deriveClock(config.algorithm, normalizeSeed(config.seed));
16
+ return "number" == typeof config.clock ? config.clock : deriveClock(config.algorithm, normalizeSalt(config.salt));
17
+ }
18
+ function mint() {
19
+ return Symbol("fabricator.instance");
16
20
  }
17
21
  function overlay(base, over) {
18
- var _ref, _over_algorithm, _base_attribution, _ref1, _over_types, _over_limits;
22
+ var _ref, _over_algorithm, _ref1, _over_types, _over_limits;
19
23
  var _this;
20
- const seed = inline(()=>{
21
- if (void 0 === over.seed) return normalizeSeed(base.seed);
22
- if (isLayered(over.seed)) return [
23
- ...normalizeSeed(base.seed),
24
- ...normalizeSeed(over.seed[Layer])
24
+ const salt = inline(()=>{
25
+ if (void 0 === over.salt) return normalizeSalt(base.salt);
26
+ if (isLayered(over.salt)) return [
27
+ ...normalizeSalt(base.salt),
28
+ ...normalizeSalt(over.salt[Layer])
25
29
  ];
26
- return normalizeSeed(over.seed);
30
+ return normalizeSalt(over.salt);
27
31
  });
28
32
  const clock = inline(()=>{
29
33
  var _base_clock;
30
- if ("seeded" === over.clock) return "seeded";
34
+ if ("derived" === over.clock) return "derived";
31
35
  if (void 0 !== over.clock) return over.clock.valueOf();
32
36
  return null != (_base_clock = base.clock) ? _base_clock : Date.now();
33
37
  });
34
38
  return {
35
- seed,
39
+ salt,
36
40
  clock,
37
41
  algorithm: null != (_ref = null != (_over_algorithm = over.algorithm) ? _over_algorithm : base.algorithm) ? _ref : defaultAlgorithm,
38
- attribution: over.attribution ? resolveAttribution(over.attribution) : null != (_base_attribution = base.attribution) ? _base_attribution : resolveAttribution(void 0),
39
42
  types: null != (_ref1 = null != (_over_types = over.types) ? _over_types : base.types) ? _ref1 : registry,
40
43
  limits: {
41
44
  combinatorial: resolveCombinatorialLimit(null == (_this = null != (_over_limits = over.limits) ? _over_limits : base.limits) ? void 0 : _this.combinatorial)
42
45
  }
43
46
  };
44
47
  }
45
- function instantiate(config, stack) {
48
+ function instantiate(config, stack, parent) {
49
+ const ancestry = void 0 === parent ? [
50
+ mint()
51
+ ] : [
52
+ ...parent.ancestry,
53
+ mint()
54
+ ];
46
55
  const source = toRandomSource({
47
- seed: config.seed,
56
+ salt: config.salt,
48
57
  algorithm: config.algorithm,
49
- attribution: config.attribution,
50
58
  clock: resolveClock(config)
51
59
  });
52
- const Fabricator = Constructor(source, stack);
53
- const { combinatorial, coverage } = enumerables(source, config.limits, stack);
60
+ const Fabricator = Constructor(source, stack, ancestry);
61
+ const { combinatorial, coverage } = enumerables(source, config.limits, stack, ancestry);
62
+ function derive(over) {
63
+ const derived = overlay(config, over);
64
+ return {
65
+ ...instantiate(derived, stack, {
66
+ ancestry,
67
+ root: instance.root
68
+ }),
69
+ config: derived
70
+ };
71
+ }
54
72
  function fork(forkOverlay = {}) {
55
- return instantiate(overlay(config, forkOverlay), stack).instance;
73
+ return derive(forkOverlay).instance;
56
74
  }
57
75
  function wrap(wrapOverlay, block) {
58
- var _ref;
59
- var _stack_current;
60
- const base = null != (_ref = null == (_stack_current = stack.current()) ? void 0 : _stack_current.config) ? _ref : config;
61
- const scopedConfig = overlay(base, wrapOverlay);
62
- const scoped = instantiate(scopedConfig, stack);
76
+ const scoped = derive(wrapOverlay);
63
77
  const result = stack.enter({
64
- config: scopedConfig,
65
- source: scoped.source
78
+ config: scoped.config,
79
+ source: scoped.source,
80
+ instance: scoped.instance,
81
+ ancestry
66
82
  }, ()=>block(scoped.instance));
67
83
  if (!stack.asynchronous && isThenable(result)) {
68
84
  result.then(noop, noop);
@@ -70,34 +86,45 @@ function instantiate(config, stack) {
70
86
  }
71
87
  return result;
72
88
  }
89
+ function visibleFrame() {
90
+ return toInnermostFrame(stack, ancestry);
91
+ }
73
92
  const context = {
74
- get seed () {
93
+ get salt () {
75
94
  var _ref;
76
- var _stack_current;
77
- return normalizeSeed((null != (_ref = null == (_stack_current = stack.current()) ? void 0 : _stack_current.config) ? _ref : config).seed);
95
+ var _visibleFrame;
96
+ return normalizeSalt((null != (_ref = null == (_visibleFrame = visibleFrame()) ? void 0 : _visibleFrame.config) ? _ref : config).salt);
78
97
  },
79
98
  get algorithm () {
80
99
  var _ref1;
81
- var _stack_current1;
82
- return (null != (_ref1 = null == (_stack_current1 = stack.current()) ? void 0 : _stack_current1.config) ? _ref1 : config).algorithm;
100
+ var _visibleFrame1;
101
+ return (null != (_ref1 = null == (_visibleFrame1 = visibleFrame()) ? void 0 : _visibleFrame1.config) ? _ref1 : config).algorithm;
83
102
  },
84
- get attribution () {
103
+ get clock () {
85
104
  var _ref2;
86
- var _stack_current2;
87
- return (null != (_ref2 = null == (_stack_current2 = stack.current()) ? void 0 : _stack_current2.config) ? _ref2 : config).attribution;
105
+ var _visibleFrame2;
106
+ return resolveClock(null != (_ref2 = null == (_visibleFrame2 = visibleFrame()) ? void 0 : _visibleFrame2.config) ? _ref2 : config);
88
107
  },
89
- get clock () {
90
- var _ref3;
91
- var _stack_current3;
92
- return resolveClock(null != (_ref3 = null == (_stack_current3 = stack.current()) ? void 0 : _stack_current3.config) ? _ref3 : config);
108
+ scope: ()=>{
109
+ var _ref;
110
+ var _visibleFrame;
111
+ return null != (_ref = null == (_visibleFrame = visibleFrame()) ? void 0 : _visibleFrame.instance) ? _ref : instance;
112
+ },
113
+ get depth () {
114
+ return stack.visible(ancestry).length;
93
115
  }
94
116
  };
95
117
  const instance = {
96
118
  T: config.types,
119
+ ancestry,
120
+ get root () {
121
+ var _ref3;
122
+ return null != (_ref3 = null == parent ? void 0 : parent.root) ? _ref3 : instance;
123
+ },
97
124
  Fabricator,
98
125
  combinatorial,
99
126
  coverage,
100
- seed: source.seed,
127
+ salt: source.salt,
101
128
  fork,
102
129
  wrap,
103
130
  context
@@ -1,10 +1,18 @@
1
1
  import { AsyncLocalStorage } from "async_hooks";
2
+ import { toVisible } from "./Visible.js";
2
3
  function toStack() {
3
4
  const store = new AsyncLocalStorage();
5
+ const getFrames = ()=>{
6
+ var _store_getStore;
7
+ return null != (_store_getStore = store.getStore()) ? _store_getStore : [];
8
+ };
4
9
  return {
5
10
  asynchronous: true,
6
- current: ()=>store.getStore(),
7
- enter: (frame, block)=>store.run(frame, block)
11
+ visible: (ancestry)=>toVisible(getFrames(), ancestry),
12
+ enter: (frame, block)=>store.run([
13
+ ...getFrames(),
14
+ frame
15
+ ], block)
8
16
  };
9
17
  }
10
18
  export { toStack };
@@ -1,8 +1,9 @@
1
+ import { toVisible } from "./Visible.js";
1
2
  function toStack() {
2
3
  const frames = [];
3
4
  return {
4
5
  asynchronous: false,
5
- current: ()=>frames[frames.length - 1],
6
+ visible: (ancestry)=>toVisible(frames, ancestry),
6
7
  enter: (frame, block)=>{
7
8
  frames.push(frame);
8
9
  try {
@@ -0,0 +1,13 @@
1
+ function onDirectLine(a, b) {
2
+ const shared = Math.min(a.length, b.length);
3
+ for(let index = 0; index < shared; index++)if (a[index] !== b[index]) return false;
4
+ return true;
5
+ }
6
+ function toVisible(frames, ancestry) {
7
+ return frames.filter((frame)=>onDirectLine(frame.ancestry, ancestry));
8
+ }
9
+ function toInnermostFrame(stack, ancestry) {
10
+ const frames = stack.visible(ancestry);
11
+ return frames[frames.length - 1];
12
+ }
13
+ export { toInnermostFrame, toVisible };
@@ -10,7 +10,7 @@ function Fabricator(context, forkSource, make) {
10
10
  function fabricateAt(depth) {
11
11
  const atMax = depth >= meta.depth.max;
12
12
  const target = atMax ? meta.terminal : meta.body;
13
- const construction = privateSource.toRoot("counted");
13
+ const construction = privateSource.toConstructionTrace();
14
14
  const context = {
15
15
  toTrace: (path, kind)=>({
16
16
  ...construction,