@playfast/reform-proof 1.3.0 → 1.4.1

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 (41) hide show
  1. package/dist/engine.d.ts +2 -2
  2. package/dist/engine.d.ts.map +1 -1
  3. package/dist/engine.js +9 -7
  4. package/dist/engine.js.map +1 -1
  5. package/dist/engineCoverage.d.ts +11 -0
  6. package/dist/engineCoverage.d.ts.map +1 -0
  7. package/dist/engineCoverage.js +48 -0
  8. package/dist/engineCoverage.js.map +1 -0
  9. package/dist/engineMounted.d.ts +4 -4
  10. package/dist/engineMounted.d.ts.map +1 -1
  11. package/dist/engineMounted.js +9 -4
  12. package/dist/engineMounted.js.map +1 -1
  13. package/dist/engineSink.d.ts +18 -1
  14. package/dist/engineSink.d.ts.map +1 -1
  15. package/dist/engineSink.js +22 -2
  16. package/dist/engineSink.js.map +1 -1
  17. package/dist/engineTreeFacade.d.ts +2 -2
  18. package/dist/engineTreeFacade.d.ts.map +1 -1
  19. package/dist/engineTreeFacade.js +42 -8
  20. package/dist/engineTreeFacade.js.map +1 -1
  21. package/dist/engineTreeTypes.d.ts +3 -1
  22. package/dist/engineTreeTypes.d.ts.map +1 -1
  23. package/dist/engineTreeTypes.js.map +1 -1
  24. package/dist/fingerprint.d.ts.map +1 -1
  25. package/dist/fingerprint.js +32 -9
  26. package/dist/fingerprint.js.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/coverage-host.test.ts +183 -0
  32. package/src/engine.ts +15 -22
  33. package/src/engineCoverage.ts +86 -0
  34. package/src/engineMounted.ts +16 -13
  35. package/src/engineSink.ts +70 -2
  36. package/src/engineTreeFacade.ts +65 -15
  37. package/src/engineTreeTypes.ts +3 -0
  38. package/src/fingerprint.ts +45 -10
  39. package/src/index.ts +1 -1
  40. package/src/proof-attribution.test.ts +210 -0
  41. package/src/test-clock.test.ts +16 -6
@@ -1,4 +1,6 @@
1
+ import * as Arr from 'effect/Array';
1
2
  import * as Option from 'effect/Option';
3
+ import * as Order from 'effect/Order';
2
4
  const readPropertyOption = Option.liftThrowable((target, key) => Reflect.get(target, key));
3
5
  const readProperty = (target, key) => Option.getOrElse(readPropertyOption(target, key), () => '[Property read threw]');
4
6
  const propertyKeyFingerprint = (key) => typeof key === 'symbol'
@@ -6,7 +8,7 @@ const propertyKeyFingerprint = (key) => typeof key === 'symbol'
6
8
  : typeof key === 'number'
7
9
  ? `number-key:${String(key)}`
8
10
  : `key:${key.length}:${key}`;
9
- const valueFingerprint = (candidate, seen) => {
11
+ const valueFingerprint = (candidate, walk) => {
10
12
  if (typeof candidate === 'bigint') {
11
13
  return `bigint:${String(candidate)}`;
12
14
  }
@@ -31,25 +33,46 @@ const valueFingerprint = (candidate, seen) => {
31
33
  if (candidate === null) {
32
34
  return 'null';
33
35
  }
34
- if (seen.has(candidate)) {
36
+ if (walk.seen.has(candidate)) {
35
37
  return '[Circular]';
36
38
  }
37
- seen.add(candidate);
39
+ const remembered = walk.memo.get(candidate);
40
+ if (remembered !== undefined) {
41
+ return remembered;
42
+ }
43
+ // `seen` marks the path currently being walked, not everything ever visited: it
44
+ // is unwound below. Without that, a value that merely repeats a reference — the
45
+ // same config object under two keys, a DAG rather than a cycle — reads as
46
+ // `[Circular]` on its second appearance, so two equal values fingerprint
47
+ // differently and `toEqual` fails on them.
48
+ walk.seen.add(candidate);
49
+ const printed = structuralFingerprint(candidate, walk);
50
+ walk.seen.delete(candidate);
51
+ // Only a print that did not depend on where the walk had been is reusable: one
52
+ // containing `[Circular]` describes this path, not this value.
53
+ if (!printed.includes('[Circular]')) {
54
+ walk.memo.set(candidate, printed);
55
+ }
56
+ return printed;
57
+ };
58
+ const structuralFingerprint = (candidate, walk) => {
38
59
  if (Array.isArray(candidate)) {
39
- return `[${candidate.map((arrayEntry) => valueFingerprint(arrayEntry, seen)).join(',')}]`;
60
+ return `[${candidate.map((arrayEntry) => valueFingerprint(arrayEntry, walk)).join(',')}]`;
40
61
  }
41
62
  if (candidate instanceof Date) {
42
63
  return `date:${String(candidate.getTime())}`;
43
64
  }
44
65
  if (candidate instanceof Map) {
45
- return `map:[${Array.from(candidate, ([mapKey, mapEntry]) => `${valueFingerprint(mapKey, seen)}=>${valueFingerprint(mapEntry, seen)}`).join(',')}]`;
66
+ return `map:[${Array.from(candidate, ([mapKey, mapEntry]) => `${valueFingerprint(mapKey, walk)}=>${valueFingerprint(mapEntry, walk)}`).join(',')}]`;
46
67
  }
47
68
  if (candidate instanceof Set) {
48
- return `set:[${Array.from(candidate, (setEntry) => valueFingerprint(setEntry, seen)).join(',')}]`;
69
+ return `set:[${Array.from(candidate, (setEntry) => valueFingerprint(setEntry, walk)).join(',')}]`;
49
70
  }
50
- return `{${Reflect.ownKeys(candidate)
51
- .map((key) => `${propertyKeyFingerprint(key)}:${valueFingerprint(readProperty(candidate, key), seen)}`)
71
+ // Sorted by key: an object is the same value however its keys were inserted, so
72
+ // reordering fields in a composition's source must not break a passing proof.
73
+ return `{${Arr.sortWith(Reflect.ownKeys(candidate).map((key) => ({ key, printed: propertyKeyFingerprint(key) })), (entry) => entry.printed, Order.string)
74
+ .map((entry) => `${entry.printed}:${valueFingerprint(readProperty(candidate, entry.key), walk)}`)
52
75
  .join(',')}}`;
53
76
  };
54
- export const formatFingerprint = (fingerprintInput) => valueFingerprint(fingerprintInput, new WeakSet());
77
+ export const formatFingerprint = (fingerprintInput) => valueFingerprint(fingerprintInput, { seen: new WeakSet(), memo: new WeakMap() });
55
78
  //# sourceMappingURL=fingerprint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,MAAM,kBAAkB,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,MAAc,EAAE,GAAgB,EAAW,EAAE,CAC5F,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CACzB,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,MAAc,EAAE,GAAgB,EAAW,EAAE,CACjE,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,uBAAuB,CAAC,CAAA;AAElF,MAAM,sBAAsB,GAAG,CAAC,GAAgB,EAAU,EAAE,CAC1D,OAAO,GAAG,KAAK,QAAQ;IACrB,CAAC,CAAC,UAAU,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;IACrC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ;QACvB,CAAC,CAAC,cAAc,MAAM,CAAC,GAAG,CAAC,EAAE;QAC7B,CAAC,CAAC,OAAO,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAA;AAElC,MAAM,gBAAgB,GAAG,CAAC,SAAkB,EAAE,IAAqB,EAAU,EAAE;IAC7E,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,UAAU,MAAM,CAAC,SAAS,CAAC,EAAE,CAAA;IACtC,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,CAAA;IACrD,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,YAAY,MAAM,CAAC,SAAS,CAAC,EAAE,CAAA;IACxC,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,UAAU,MAAM,CAAC,SAAS,CAAC,EAAE,CAAA;IACtC,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,UAAU,SAAS,CAAC,MAAM,IAAI,SAAS,EAAE,CAAA;IAClD,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,UAAU,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAA;IAClD,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC;QACrC,OAAO,WAAW,CAAA;IACpB,CAAC;IACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,MAAM,CAAA;IACf,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACxB,OAAO,YAAY,CAAA;IACrB,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACnB,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;IAC3F,CAAC;IACD,IAAI,SAAS,YAAY,IAAI,EAAE,CAAC;QAC9B,OAAO,QAAQ,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;IAC9C,CAAC;IACD,IAAI,SAAS,YAAY,GAAG,EAAE,CAAC;QAC7B,OAAO,QAAQ,KAAK,CAAC,IAAI,CACvB,SAAS,EACT,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,CACrB,GAAG,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAC3E,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;IAChB,CAAC;IACD,IAAI,SAAS,YAAY,GAAG,EAAE,CAAC;QAC7B,OAAO,QAAQ,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACvF,GAAG,CACJ,GAAG,CAAA;IACN,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;SAClC,GAAG,CACF,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,sBAAsB,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAC3F;SACA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,gBAAyB,EAAU,EAAE,CACrE,gBAAgB,CAAC,gBAAgB,EAAE,IAAI,OAAO,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ import type { AnyScene, CapturedRender } from '@playfast/reform/internal';
8
8
  export { ProofRunner, proofRunnerLayer, withProofRunner };
9
9
  export type { ProofRunnerApi };
10
10
  export { makeFacade, makeProofFacade, makeRuntimeHandleFacade, makeRuntimeTreeFacade, makeSink, proofLayer, } from './engine.js';
11
- export type { MountedFacade, MountedSlotFacade, MountedSlotFacadesOf, RuntimeTreeFacade, Sink, } from './engine.js';
11
+ export type { DispatchedAction, MountedFacade, MountedSlotFacade, MountedSlotFacadesOf, RuntimeTreeFacade, Sink, } from './engine.js';
12
12
  export { Product, ProductRequirement } from './product.js';
13
13
  export type { AnyRequirementClass, ProductClass, ProductComposition, ProductManifest, RequirementCapture, RequirementClass, RequirementManifest, } from './product.js';
14
14
  export { expect, matchProps } from './assert.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAe,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAA;AACtE,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC3D,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,YAAY,EAAa,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,KAAK,EAEV,KAAK,EACL,eAAe,IAAI,qBAAqB,EACxC,UAAU,EACX,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAEzE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAA;AACzD,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,OAAO,EACL,UAAU,EACV,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,QAAQ,EACR,UAAU,GACX,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,IAAI,GACL,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACvD,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC7C,YAAY,EACV,MAAM,EACN,SAAS,EACT,UAAU,EACV,QAAQ,EACR,MAAM,EACN,UAAU,EACV,aAAa,GACd,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEpF,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAA;IACzC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,MAAM,CAAA;CAClE;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;CACtC;AAED,QAAA,MAAM,SAAS,GAAI,IAAI,SAAS,kBAAkB,EAChD,aAAa,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,EAC3C,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAChE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,KAAK,cAAc,KAC7D,KA0BA,CAAA;AAEH,KAAK,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,SAAS,kBAAkB,IAAI,CAAC,SAAS;IACrF,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;CACjD,GACG;KACG,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;CAC7F,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,GACnB,KAAK,CAAA;AAET,KAAK,YAAY,CACf,IAAI,SAAS,kBAAkB,EAC/B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,IAC9B,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEjE,QAAA,MAAM,YAAY,GAChB,IAAI,SAAS,kBAAkB,EAC/B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAEhC,aAAa,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,EAC3C,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACxC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,cAAc,KAC9C,KAiBA,CAAA;AAEH,UAAU,eAAe;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;CACtC;AAED,QAAA,MAAM,KAAK,GAAI,SAAS,YAAY,EAAE,QAAQ,eAAe,KAAG,UAI9D,CAAA;AAEF,eAAO,MAAM,YAAY,GAAI,WAAW,OAAO,KAAG,SAAS,IAAI,UACkC,CAAA;AAEjG,QAAA,MAAM,GAAG,GAAI,YAAY,UAAU,KAAG,OAAO,CAAC,WAAW,CACf,CAAA;AAE1C,QAAA,MAAM,SAAS,GAAI,YAAY,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAWhF,CAAA;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;IACzC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAA;CACzC;AAED,QAAA,MAAM,MAAM,GAAI,YAAY,UAAU,KAAG,aAAa,CAAC,WAAW,CAI7D,CAAA;AAEL;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,aAAa,GAAI,IAAI,EAAE,CAAC,EAAE,GAAG,EACjC,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,KAC/B,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,YAAY,EAAE,CAAC,EAAE,GAAG,CACE,CAAA;AAEzD,eAAO,MAAM,KAAK,EAAE;IAClB,QAAQ,CAAC,SAAS,EAAE,OAAO,SAAS,CAAA;IACpC,QAAQ,CAAC,YAAY,EAAE,OAAO,YAAY,CAAA;IAC1C,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,OAAO,SAAS,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,OAAO,aAAa,CAAA;CAC+B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playfast/reform-proof",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "Headless testing toolkit for reform — drive a scene's compositions and assert on the props they compute, with no DOM, timers, or text matching.",
5
5
  "keywords": [
6
6
  "effect",
@@ -0,0 +1,183 @@
1
+ import { Layer, Schema as S } from 'effect'
2
+ import {
3
+ Composition,
4
+ Engine,
5
+ Event,
6
+ mount,
7
+ one,
8
+ provide,
9
+ Reducer,
10
+ scene,
11
+ slot,
12
+ State,
13
+ StateGroup,
14
+ type Trigger,
15
+ Ui,
16
+ ui,
17
+ } from '@playfast/reform'
18
+ import { describe, expect, test } from 'vitest'
19
+ import { Product, Proof, ProductRequirement, expect as proofExpect } from './index'
20
+
21
+ // The dialog's own event, and one only the host raises.
22
+ class Confirmed extends Event.make('CovConfirmed', S.Struct({})) {}
23
+ class HostConfirmed extends Event.make('CovHostConfirmed', S.Struct({})) {}
24
+
25
+ class CountState extends State.make('covCount', S.Number) {}
26
+ class CountStates extends StateGroup.make(CountState) {}
27
+ class CountReducer extends Reducer.make('CovReducer', {
28
+ states: [CountState],
29
+ events: [Confirmed],
30
+ }) {}
31
+ const CountReducerLive = Reducer.live(CountReducer, (count) => count + 1)
32
+
33
+ class DialogUi extends ui('CovDialog')<{
34
+ props: { count: number }
35
+ events: { confirm: Trigger<Record<string, never>> }
36
+ }>() {}
37
+ class Dialog extends Composition.make('CovDialog', {
38
+ title: 'CovDialog',
39
+ states: [CountStates],
40
+ events: [Confirmed],
41
+ ui: DialogUi,
42
+ })<Dialog>() {}
43
+ const DialogLive = Composition.live(Dialog, function* () {
44
+ const count = yield* StateGroup.select(CountStates, 'covCount')
45
+ const confirm = yield* Event.trigger(Confirmed)
46
+ return mount({ props: { count }, slots: {}, events: { confirm } })
47
+ })
48
+ class DialogSlot extends slot('CovDialogSlot')<DialogSlot, typeof Dialog>() {}
49
+
50
+ // A sibling that raises the dialog's event without being the dialog.
51
+ class EchoUi extends ui('CovEcho')<{
52
+ props: { count: number }
53
+ events: { confirm: Trigger<Record<string, never>> }
54
+ }>() {}
55
+ class Echo extends Composition.make('CovEcho', {
56
+ title: 'CovEcho',
57
+ states: [CountStates],
58
+ events: [Confirmed],
59
+ ui: EchoUi,
60
+ })<Echo>() {}
61
+ const EchoLive = Composition.live(Echo, function* () {
62
+ const count = yield* StateGroup.select(CountStates, 'covCount')
63
+ const confirm = yield* Event.trigger(Confirmed)
64
+ return mount({ props: { count }, slots: {}, events: { confirm } })
65
+ })
66
+ class EchoSlot extends slot('CovEchoSlot')<EchoSlot, typeof Echo>() {}
67
+
68
+ // The test-only parent: it renders the dialog and re-exposes its event as
69
+ // `passthrough`, while its own `confirm` is a different event that happens to
70
+ // spell the dialog's action name.
71
+ class HostUi extends ui('CovHost')<{
72
+ props: { count: number }
73
+ events: {
74
+ confirm: Trigger<Record<string, never>>
75
+ passthrough: Trigger<Record<string, never>>
76
+ }
77
+ slots: { Dialog: DialogSlot; Echo: EchoSlot }
78
+ }>() {}
79
+ class Host extends Composition.make('CovHost', {
80
+ title: 'CovHost',
81
+ states: [CountStates],
82
+ events: [Confirmed, HostConfirmed],
83
+ slots: { Dialog: DialogSlot, Echo: EchoSlot },
84
+ ui: HostUi,
85
+ })<Host>() {}
86
+ const HostLive = Composition.live(Host, function* () {
87
+ const count = yield* StateGroup.select(CountStates, 'covCount')
88
+ const confirm = yield* Event.trigger(HostConfirmed)
89
+ const passthrough = yield* Event.trigger(Confirmed)
90
+ return mount({
91
+ props: { count },
92
+ slots: { Dialog: one({}), Echo: one({}) },
93
+ events: { confirm, passthrough },
94
+ })
95
+ })
96
+
97
+ const presentations = Layer.mergeAll(
98
+ provide(
99
+ HostUi,
100
+ Ui.make(HostUi, () => null),
101
+ ),
102
+ provide(
103
+ DialogUi,
104
+ Ui.make(DialogUi, () => null),
105
+ ),
106
+ provide(
107
+ EchoUi,
108
+ Ui.make(EchoUi, () => null),
109
+ ),
110
+ )
111
+ const Views = Layer.mergeAll(
112
+ HostLive,
113
+ DialogLive,
114
+ EchoLive,
115
+ provide(DialogSlot, Dialog),
116
+ provide(EchoSlot, Echo),
117
+ ).pipe(Layer.provideMerge(presentations))
118
+ const Logic = CountReducerLive.pipe(
119
+ Layer.provideMerge(Layer.mergeAll(Engine, StateGroup.live(CountStates, { covCount: 0 }))),
120
+ )
121
+ const HostScene = scene(Host, { provide: [Views.pipe(Layer.provideMerge(Logic))] })
122
+
123
+ class ConfirmsDialog extends ProductRequirement.make(Dialog, 'confirms the dialog', {
124
+ events: ['confirm'],
125
+ }) {}
126
+ class DialogProduct extends Product.make(Dialog, { requirements: [ConfirmsDialog] }) {}
127
+
128
+ const run = (proof: Proof) => Proof.run(Proof.suite(DialogProduct, { proofs: [proof] }))
129
+
130
+ describe('event coverage across a test-only host (issue #26)', () => {
131
+ test('the composition raising the requirement’s own event covers it', async () => {
132
+ const viaSlot = Proof.implementVia(ConfirmsDialog, HostScene, function* (app) {
133
+ const dialog = yield* app.slots.Dialog.first
134
+ const after = yield* dialog.actions.confirm({})
135
+ yield* proofExpect(after.count).toBe(1)
136
+ })
137
+ const result = await run(viaSlot)
138
+ expect(result.results[0]?.error).toBeUndefined()
139
+ expect(result.ok).toBe(true)
140
+ })
141
+
142
+ test('a host that re-raises the requirement’s event covers it too', async () => {
143
+ const viaHost = Proof.implementVia(ConfirmsDialog, HostScene, function* (app) {
144
+ const after = yield* app.actions.passthrough({})
145
+ yield* proofExpect(after.count).toBe(1)
146
+ })
147
+ const result = await run(viaHost)
148
+ expect(result.results[0]?.error).toBeUndefined()
149
+ expect(result.ok).toBe(true)
150
+ })
151
+
152
+ test('a host action that only spells the name the same does not cover it', async () => {
153
+ const sameName = Proof.implementVia(ConfirmsDialog, HostScene, function* (app) {
154
+ const after = yield* app.actions.confirm({})
155
+ yield* proofExpect(after.count).toBe(0)
156
+ })
157
+ const result = await run(sameName)
158
+ expect(result.ok).toBe(false)
159
+ expect(result.results[0]?.error).toContain('never dispatched')
160
+ })
161
+
162
+ test('a sibling raising the same event does not cover it', async () => {
163
+ const sibling = Proof.implementVia(ConfirmsDialog, HostScene, function* (app) {
164
+ const echo = yield* app.slots.Echo.first
165
+ const after = yield* echo.actions.confirm({})
166
+ yield* proofExpect(after.count).toBe(1)
167
+ })
168
+ const result = await run(sibling)
169
+ expect(result.ok).toBe(false)
170
+ expect(result.results[0]?.error).toContain('never dispatched')
171
+ })
172
+
173
+ test('the failure names where the event was dispatched instead', async () => {
174
+ const sameName = Proof.implementVia(ConfirmsDialog, HostScene, function* (app) {
175
+ yield* app.actions.confirm({})
176
+ })
177
+ const result = await run(sameName)
178
+ expect(result.results[0]?.error).toContain('dispatched on CovHost')
179
+ expect(result.results[0]?.error).toContain('CovHostConfirmed')
180
+ expect(result.results[0]?.error).toContain('not on CovDialog')
181
+ expect(result.results[0]?.error).toContain('CovConfirmed')
182
+ })
183
+ })
package/src/engine.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  } from '@playfast/reform'
10
10
  import { type AnyComposition, type AnyScene } from '@playfast/reform/internal'
11
11
  import {
12
+ type DispatchedAction,
12
13
  invalidCompositionProps,
13
14
  type HostRuntime,
14
15
  makeSink,
@@ -17,6 +18,7 @@ import {
17
18
  type Sink,
18
19
  } from './engineSink'
19
20
  import { childComposition, readRuntimeSlotChild, slotsOf } from './engineTree'
21
+ import { type Coverage, coverageFailure, missingCoverage } from './engineCoverage'
20
22
  import type { RuntimeTreeFacade } from './engineTreeTypes'
21
23
  import { makeRuntimeTreeFacade } from './engineTreeFacade'
22
24
  import type { ProofCase, ProofResult } from './proofCase'
@@ -26,14 +28,10 @@ import type { ProductComposition } from './product'
26
28
  import type { Proof } from './index'
27
29
 
28
30
  export { makeSink } from './engineSink'
29
- export type { Sink } from './engineSink'
31
+ export type { DispatchedAction, Sink } from './engineSink'
30
32
  export { proofLayer } from './engineTree'
31
33
  export { makeFacade, makeProofFacade, makeRuntimeHandleFacade } from './engineMounted'
32
- export type {
33
- MountedFacade,
34
- MountedSlotFacade,
35
- MountedSlotFacadesOf,
36
- } from './engineSink'
34
+ export type { MountedFacade, MountedSlotFacade, MountedSlotFacadesOf } from './engineSink'
37
35
  export { makeRuntimeTreeFacade } from './engineTreeFacade'
38
36
  export type { RuntimeTreeFacade } from './engineTreeTypes'
39
37
 
@@ -63,7 +61,7 @@ const withProofRuntimeTree = <
63
61
  >(
64
62
  scene: CapturedScene<C, S, Services, P, N, Identity>,
65
63
  sink: Sink,
66
- dispatched: Set<string>,
64
+ dispatched: Set<DispatchedAction>,
67
65
  use: (runtime: HostRuntime, tree: RuntimeTreeFacade<C>) => Effect.Effect<A, E, never>,
68
66
  ): Effect.Effect<A, E, never> =>
69
67
  Effect.acquireUseRelease(
@@ -81,15 +79,6 @@ const withProofRuntimeTree = <
81
79
  (runtime) => Effect.sync(runtime.dispose),
82
80
  )
83
81
 
84
- const missingCoverage = (
85
- proof: Pick<Proof, 'requirement'>,
86
- dispatched: Set<string>,
87
- ): ReadonlyArray<string> =>
88
- Option.match(proof.requirement.manifest.events, {
89
- onNone: () => [],
90
- onSome: (declared) => declared.map(String).filter((event) => !dispatched.has(event)),
91
- })
92
-
93
82
  interface ProofPlacement {
94
83
  readonly requirement: Proof['requirement']
95
84
  readonly placement: 'Root' | 'Slot'
@@ -144,7 +133,7 @@ const executeProofWithSink = Effect.fn('executeProofWithSink')(function* <
144
133
  scene: CapturedScene<C, S, Services, P, N, Identity>,
145
134
  sink: Sink,
146
135
  ): Effect.fn.Return<ProofResult, never, never> {
147
- const dispatched = new Set<string>()
136
+ const dispatched = new Set<DispatchedAction>()
148
137
  const statement = proof.requirement.manifest.statement
149
138
  const runGenerator = Effect.fn('runProofGenerator')(function* (
150
139
  generator: ReturnType<typeof proof.body>,
@@ -164,10 +153,15 @@ const executeProofWithSink = Effect.fn('executeProofWithSink')(function* <
164
153
  yield* verifyProofPlacement(proof, scene, runtime)
165
154
  yield* tree.settle
166
155
  yield* runGenerator(proof.body(tree.facade), undefined, tree.settle)
167
- const missing = missingCoverage(proof, dispatched)
168
- const coverageError = `requirement declares events never dispatched: ${missing.join(', ')}`
156
+ const coverage: Coverage = {
157
+ requirement: proof.requirement,
158
+ host: compositionIdentity(scene.composition),
159
+ dispatched,
160
+ publications: tree.publications,
161
+ }
162
+ const missing = missingCoverage(coverage)
169
163
  return missing.length > 0
170
- ? { requirement: statement, ok: false, error: coverageError }
164
+ ? { requirement: statement, ok: false, error: coverageFailure(coverage, missing) }
171
165
  : { requirement: statement, ok: true, error: undefined }
172
166
  }),
173
167
  ).pipe(
@@ -218,7 +212,7 @@ const driveProofWithSink = Effect.fn('driveProofWithSink')(function* <
218
212
  const frames = yield* Ref.make<ReadonlyArray<StepFrame>>([])
219
213
  const statement = proof.requirement.manifest.statement
220
214
  // Driving tracks dispatches for the facade without enforcing coverage.
221
- const dispatched = new Set<string>()
215
+ const dispatched = new Set<DispatchedAction>()
222
216
  const record = (index: number): Effect.Effect<void> =>
223
217
  Ref.update(frames, (current) => [...current, { index, captures: [...sink.captures] }])
224
218
  const pump = Effect.fn('pump')(function* (
@@ -282,4 +276,3 @@ export const driveProofEffect = (proof: Proof): Effect.Effect<DriveResult, never
282
276
 
283
277
  export const driveProof = (proof: Proof): Promise<DriveResult> =>
284
278
  Effect.runPromise(driveProofEffect(proof))
285
-
@@ -0,0 +1,86 @@
1
+ import { Array as Arr, Option } from 'effect'
2
+ import { compositionIdentityOf, type DispatchedAction, type EventPublications } from './engineSink'
3
+ import type { Proof } from './index'
4
+
5
+ export interface Coverage {
6
+ readonly requirement: Proof['requirement']
7
+ // The scene root — the composition that renders the requirement's own, and the only
8
+ // one whose dispatch can stand in for it.
9
+ readonly host: symbol
10
+ readonly dispatched: Set<DispatchedAction>
11
+ readonly publications: EventPublications
12
+ }
13
+
14
+ interface DeclaredEvent {
15
+ readonly coverage: Coverage
16
+ readonly owner: symbol
17
+ readonly event: string
18
+ }
19
+
20
+ const samePublication = (
21
+ published: Option.Option<string>,
22
+ declared: Option.Option<string>,
23
+ ): boolean =>
24
+ Option.getOrElse(
25
+ Option.zipWith(published, declared, (raised, owned) => raised === owned),
26
+ () => false,
27
+ )
28
+
29
+ // A declared event is answered by a dispatch on the requirement's own composition — or
30
+ // by the composition that renders it raising the very same domain Event. The second
31
+ // case is the test-only parent that exists to feed a slot the props it needs and
32
+ // re-exposes its action: that dispatch reaches the child's reducer, so withholding
33
+ // coverage reports "never dispatched" about an event whose effects the proof body
34
+ // asserts two lines later. A composition that merely spells an action the same way
35
+ // publishes a different Event and stays uncovered, which is the collision the identity
36
+ // check exists for — as does a sibling raising the event without owning the action.
37
+ const answeredBy =
38
+ ({ coverage, owner, event }: DeclaredEvent) =>
39
+ (action: DispatchedAction): boolean =>
40
+ Object.is(action.identity, owner)
41
+ ? action.event === event
42
+ : Object.is(action.identity, coverage.host) &&
43
+ samePublication(action.published, coverage.publications.publishedBy(owner, event))
44
+
45
+ export const missingCoverage = (coverage: Coverage): ReadonlyArray<string> =>
46
+ Option.match(coverage.requirement.manifest.events, {
47
+ onNone: () => [],
48
+ onSome: (declared) => {
49
+ const owner = compositionIdentityOf(coverage.requirement.manifest.composition)
50
+ const raised = Arr.fromIterable(coverage.dispatched)
51
+ return declared
52
+ .map(String)
53
+ .filter((event) => !raised.some(answeredBy({ coverage, owner, event })))
54
+ },
55
+ })
56
+
57
+ const publicationSuffix = (published: Option.Option<string>): string =>
58
+ Option.match(published, {
59
+ onNone: () => '',
60
+ onSome: (tag) => ` (publishes ${tag})`,
61
+ })
62
+
63
+ // "never dispatched" is the wrong story when the event was dispatched on a composition
64
+ // the requirement does not own, so name that composition and what each side publishes.
65
+ const uncoveredDetail = ({ coverage, owner, event }: DeclaredEvent): string => {
66
+ const ownerName = coverage.requirement.manifest.composition.manifest.name
67
+ const elsewhere = Arr.dedupe(
68
+ Arr.filterMap(Arr.fromIterable(coverage.dispatched), (action) =>
69
+ action.event === event && !Object.is(action.identity, owner)
70
+ ? Option.some(`${action.composition}${publicationSuffix(action.published)}`)
71
+ : Option.none(),
72
+ ),
73
+ )
74
+ const owned = publicationSuffix(coverage.publications.publishedBy(owner, event))
75
+ return Arr.match(elsewhere, {
76
+ onEmpty: () => event,
77
+ onNonEmpty: (raisers) =>
78
+ `${event} — dispatched on ${Arr.join(raisers, ', ')}, not on ${ownerName}${owned}`,
79
+ })
80
+ }
81
+
82
+ export const coverageFailure = (coverage: Coverage, missing: ReadonlyArray<string>): string => {
83
+ const owner = compositionIdentityOf(coverage.requirement.manifest.composition)
84
+ const detail = missing.map((event) => uncoveredDetail({ coverage, owner, event }))
85
+ return `requirement declares events never dispatched: ${Arr.join(detail, '; ')}`
86
+ }
@@ -7,10 +7,12 @@ import {
7
7
  type Trigger,
8
8
  type UiContract,
9
9
  } from '@playfast/reform'
10
- import { type AnyComposition, CaptureSink } from '@playfast/reform/internal'
10
+ import { type AnyComposition, CaptureSink, triggerEventTag } from '@playfast/reform/internal'
11
11
  import type { Facade } from './facade'
12
12
  import {
13
+ compositionIdentityOf,
13
14
  directSettle,
15
+ type DispatchedAction,
14
16
  expectMatchingProps,
15
17
  keyed,
16
18
  type MountedFacade,
@@ -32,11 +34,7 @@ import {
32
34
  slotCapturesFor,
33
35
  slotsOf,
34
36
  } from './engineTree'
35
- import {
36
- collectRuntimeBindings,
37
- renderTreeRuntime,
38
- settleTreeRuntime,
39
- } from './engineRender'
37
+ import { collectRuntimeBindings, renderTreeRuntime, settleTreeRuntime } from './engineRender'
40
38
 
41
39
  export function makeFacade<
42
40
  C extends UiContract,
@@ -49,7 +47,7 @@ export function makeFacade<
49
47
  runtime: ManagedRuntime.ManagedRuntime<Services | CaptureSink, never>,
50
48
  scene: CapturedScene<C, S, Services, P, N, Identity>,
51
49
  sink: Sink,
52
- dispatched: Set<string>,
50
+ dispatched: Set<DispatchedAction>,
53
51
  ): {
54
52
  readonly facade: Facade<C, never>
55
53
  readonly settle: Effect.Effect<void, never, never>
@@ -74,7 +72,7 @@ function makeMountedFacade<
74
72
  runtime: RenderRuntime,
75
73
  root: CompositionClass<P, C, S, N, Identity>,
76
74
  sink: Sink,
77
- dispatched: Set<string>,
75
+ dispatched: Set<DispatchedAction>,
78
76
  settleBoundary: SettleBoundary,
79
77
  ): {
80
78
  readonly facade: MountedFacade<C>
@@ -84,14 +82,14 @@ function makeMountedFacade(
84
82
  runtime: RenderRuntime,
85
83
  root: AnyComposition,
86
84
  sink: Sink,
87
- dispatched: Set<string>,
85
+ dispatched: Set<DispatchedAction>,
88
86
  settleBoundary: SettleBoundary,
89
87
  ): MountedFacadeHandleErasure
90
88
  function makeMountedFacade(
91
89
  runtime: RenderRuntime,
92
90
  root: AnyComposition,
93
91
  sink: Sink,
94
- dispatched: Set<string>,
92
+ dispatched: Set<DispatchedAction>,
95
93
  settleBoundary: SettleBoundary,
96
94
  ): MountedFacadeHandleErasure {
97
95
  const bindings = collectRuntimeBindings(root, runtime)
@@ -146,7 +144,12 @@ function makeMountedFacade(
146
144
  Effect.flatMap(() => triggerOf(ref, event)),
147
145
  Effect.flatMap((trigger) =>
148
146
  Effect.sync(() => {
149
- dispatched.add(event)
147
+ dispatched.add({
148
+ identity: compositionIdentityOf(comp),
149
+ composition: uiNameOf(comp),
150
+ event,
151
+ published: triggerEventTag(trigger),
152
+ })
150
153
  trigger(payload)
151
154
  }),
152
155
  ),
@@ -244,7 +247,7 @@ export const makeProofFacade = <
244
247
  runtime: ManagedRuntime.ManagedRuntime<Services | CaptureSink, never>,
245
248
  scene: CapturedScene<C, S, Services, P, N, Identity>,
246
249
  sink: Sink,
247
- dispatched: Set<string>,
250
+ dispatched: Set<DispatchedAction>,
248
251
  ): {
249
252
  readonly facade: Facade<C, never>
250
253
  readonly settle: Effect.Effect<void, never, never>
@@ -264,7 +267,7 @@ export const makeRuntimeHandleFacade = <
264
267
  runtime: RuntimeHandle<Services>,
265
268
  root: RuntimeRootComposition<RootIdentifier, P, C, S, N, Identity>,
266
269
  sink: Sink,
267
- dispatched: Set<string>,
270
+ dispatched: Set<DispatchedAction>,
268
271
  ): {
269
272
  readonly facade: MountedFacade<C>
270
273
  readonly settle: Effect.Effect<void, never, never>