foldkit 0.133.0 → 0.135.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 (88) hide show
  1. package/README.md +13 -17
  2. package/dist/canvas/view.d.ts +18 -11
  3. package/dist/canvas/view.d.ts.map +1 -1
  4. package/dist/canvas/view.js +18 -11
  5. package/dist/customElement/index.d.ts +12 -6
  6. package/dist/customElement/index.d.ts.map +1 -1
  7. package/dist/customElement/index.js +17 -4
  8. package/dist/html/index.d.ts +625 -1601
  9. package/dist/html/index.d.ts.map +1 -1
  10. package/dist/html/index.js +52 -15
  11. package/dist/html/public.d.ts +2 -2
  12. package/dist/html/public.d.ts.map +1 -1
  13. package/dist/html/public.js +1 -1
  14. package/dist/html/runtimeSingleton.d.ts +1 -1
  15. package/dist/html/runtimeSingleton.d.ts.map +1 -1
  16. package/dist/html/runtimeSingleton.js +1 -1
  17. package/dist/html/submodel.d.ts +51 -19
  18. package/dist/html/submodel.d.ts.map +1 -1
  19. package/dist/html/submodel.js +37 -13
  20. package/dist/managedResource/managedResource.d.ts +21 -10
  21. package/dist/managedResource/managedResource.d.ts.map +1 -1
  22. package/dist/managedResource/managedResource.js +6 -1
  23. package/dist/runtime/crashUI.d.ts.map +1 -1
  24. package/dist/runtime/crashUI.js +29 -30
  25. package/dist/runtime/runtime.d.ts +9 -6
  26. package/dist/runtime/runtime.d.ts.map +1 -1
  27. package/dist/runtime/runtime.js +9 -8
  28. package/dist/test/apps/attributes.d.ts +2 -2
  29. package/dist/test/apps/attributes.d.ts.map +1 -1
  30. package/dist/test/apps/attributes.js +1 -3
  31. package/dist/test/apps/bubbling.d.ts +2 -2
  32. package/dist/test/apps/bubbling.d.ts.map +1 -1
  33. package/dist/test/apps/bubbling.js +1 -3
  34. package/dist/test/apps/colorPicker.d.ts +28 -0
  35. package/dist/test/apps/colorPicker.d.ts.map +1 -0
  36. package/dist/test/apps/colorPicker.js +43 -0
  37. package/dist/test/apps/counter.d.ts +5 -3
  38. package/dist/test/apps/counter.d.ts.map +1 -1
  39. package/dist/test/apps/counter.js +12 -7
  40. package/dist/test/apps/crashOnRender.d.ts +2 -2
  41. package/dist/test/apps/crashOnRender.d.ts.map +1 -1
  42. package/dist/test/apps/crashOnRender.js +1 -3
  43. package/dist/test/apps/drafts.d.ts +2 -2
  44. package/dist/test/apps/drafts.d.ts.map +1 -1
  45. package/dist/test/apps/drafts.js +1 -3
  46. package/dist/test/apps/feedSocket.d.ts +74 -0
  47. package/dist/test/apps/feedSocket.d.ts.map +1 -0
  48. package/dist/test/apps/feedSocket.js +69 -0
  49. package/dist/test/apps/fileUpload.d.ts +2 -2
  50. package/dist/test/apps/fileUpload.d.ts.map +1 -1
  51. package/dist/test/apps/fileUpload.js +1 -3
  52. package/dist/test/apps/interactions.d.ts +2 -2
  53. package/dist/test/apps/interactions.d.ts.map +1 -1
  54. package/dist/test/apps/interactions.js +1 -3
  55. package/dist/test/apps/keypress.d.ts +2 -2
  56. package/dist/test/apps/keypress.d.ts.map +1 -1
  57. package/dist/test/apps/keypress.js +1 -3
  58. package/dist/test/apps/login.d.ts +2 -2
  59. package/dist/test/apps/login.d.ts.map +1 -1
  60. package/dist/test/apps/login.js +1 -3
  61. package/dist/test/apps/logoutButton.d.ts +2 -2
  62. package/dist/test/apps/logoutButton.d.ts.map +1 -1
  63. package/dist/test/apps/logoutButton.js +1 -3
  64. package/dist/test/apps/mountPanel.d.ts +4 -4
  65. package/dist/test/apps/mountPanel.d.ts.map +1 -1
  66. package/dist/test/apps/mountPanel.js +3 -7
  67. package/dist/test/apps/multiRole.d.ts +2 -2
  68. package/dist/test/apps/multiRole.d.ts.map +1 -1
  69. package/dist/test/apps/multiRole.js +1 -3
  70. package/dist/test/apps/pointer.d.ts +2 -2
  71. package/dist/test/apps/pointer.d.ts.map +1 -1
  72. package/dist/test/apps/pointer.js +1 -3
  73. package/dist/test/apps/resumeUpload.d.ts +2 -2
  74. package/dist/test/apps/resumeUpload.d.ts.map +1 -1
  75. package/dist/test/apps/resumeUpload.js +3 -6
  76. package/dist/test/apps/scorePanel.d.ts +32 -0
  77. package/dist/test/apps/scorePanel.d.ts.map +1 -0
  78. package/dist/test/apps/scorePanel.js +19 -0
  79. package/dist/test/apps/uploads.d.ts +2 -2
  80. package/dist/test/apps/uploads.d.ts.map +1 -1
  81. package/dist/test/apps/uploads.js +1 -3
  82. package/dist/test/scene.d.ts +81 -9
  83. package/dist/test/scene.d.ts.map +1 -1
  84. package/dist/test/scene.js +206 -26
  85. package/dist/test/story.d.ts +4 -5
  86. package/dist/test/story.d.ts.map +1 -1
  87. package/dist/test/story.js +1 -2
  88. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
- import { Array, Context, Effect, Function, Option, Predicate, String as String_, pipe, } from 'effect';
1
+ import { Array, Context, Effect, Equal, Function, Option, Predicate, String as String_, pipe, } from 'effect';
2
2
  import { dual } from 'effect/Function';
3
- import { FOLDKIT_MOUNT_KEY, FileHandlerSymbol, __clearRuntime as clearHtmlRuntime, __setRuntime as setHtmlRuntime, } from '../html/index.js';
3
+ import { kebabToPascal } from '../customElement/index.js';
4
+ import { FOLDKIT_MOUNT_KEY, FileHandlerSymbol, __clearRuntime as clearHtmlRuntime, __htmlBuilder as htmlBuilderFor, __setRuntime as setHtmlRuntime, } from '../html/index.js';
4
5
  import { MountTracker } from '../mount/index.js';
5
6
  import { Dispatch } from '../runtime/index.js';
6
7
  import { assertAllCommandsResolved, assertAllMountsResolved, assertAllUnmountsAcknowledged, assertExactCommands, assertExactMounts, assertHasCommands, assertHasMounts, assertNoUnacknowledgedUnmounts, assertNoUnresolvedCommands, assertNoUnresolvedMounts, assertResolveUnambiguous, assertZeroCommands, assertZeroMounts, formatCommand, formatMatcher, formatMountList, formatMountMatcher, mountMatches, resolveAllInternal, resolveByMatcher, resolveMountByMatcher, } from './internal.js';
@@ -128,7 +129,7 @@ const renderView = (viewFn, model, dispatch) => {
128
129
  setHtmlRuntime(dispatch.dispatchSync, sceneContext);
129
130
  let result;
130
131
  try {
131
- result = viewFn(model);
132
+ result = viewFn(model, htmlBuilderFor());
132
133
  }
133
134
  finally {
134
135
  clearHtmlRuntime();
@@ -157,7 +158,7 @@ const EVENT_NAMES = {
157
158
  pointerdown: 'OnPointerDown',
158
159
  pointerup: 'OnPointerUp',
159
160
  };
160
- const captureFromElement = (simulation, element, description, eventName, invokeHandler) => {
161
+ const maybeCaptureFromElement = (simulation, element, description, eventName, invokeHandler) => {
161
162
  const internal = toInternal(simulation);
162
163
  const maybeHandler = Option.fromNullishOr(element.data?.on?.[eventName]);
163
164
  if (Option.isNone(maybeHandler)) {
@@ -168,27 +169,9 @@ const captureFromElement = (simulation, element, description, eventName, invokeH
168
169
  internal.capturingDispatch.reset();
169
170
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
170
171
  invokeHandler(maybeHandler.value);
171
- const captured = internal.capturingDispatch.getCapturedMessage();
172
- if (Predicate.isUndefined(captured)) {
173
- return simulation;
174
- }
175
- assertNoUnresolvedCommands(internal.commands, 'when an interaction dispatched a new Message');
176
- assertNoUnresolvedMounts(internal.mounts, 'when an interaction dispatched a new Message');
177
- assertNoUnacknowledgedUnmounts(unacknowledgedEndedMountsOf(internal.mountSlots), 'when an interaction dispatched a new Message');
178
- /* eslint-disable @typescript-eslint/consistent-type-assertions */
179
- const capturedMessage = captured;
180
- const result = internal.updateFn(internal.model, capturedMessage);
181
- const [nextModel, commands] = result;
182
- const outMessage = result.length === 3 ? result[2] : internal.outMessage;
183
- return {
184
- ...internal,
185
- model: nextModel,
186
- message: capturedMessage,
187
- commands: Array.appendAll(internal.commands, commands),
188
- outMessage,
189
- };
190
- /* eslint-enable @typescript-eslint/consistent-type-assertions */
172
+ return Option.map(Option.fromNullishOr(internal.capturingDispatch.getCapturedMessage()), captured => applyExternalMessage(simulation, captured, 'when an interaction dispatched a new Message'));
191
173
  };
174
+ const captureFromElement = (simulation, element, description, eventName, invokeHandler) => Option.getOrElse(maybeCaptureFromElement(simulation, element, description, eventName, invokeHandler), () => simulation);
192
175
  const invokeAndCapture = (simulation, target, eventName, invokeHandler) => {
193
176
  const internal = toInternal(simulation);
194
177
  const scopedTarget = applyScopeToTarget(internal.scope, target);
@@ -262,8 +245,7 @@ const assertFileHandler = (handler, expectedTag, helperName) => {
262
245
  };
263
246
  // STEPS
264
247
  /** Sets the initial Model for a scene test. */
265
- export { with_ as with };
266
- const with_ = (model) => {
248
+ export const given = (model) => {
267
249
  const step = (simulation) => {
268
250
  const internal = toInternal(simulation);
269
251
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -415,6 +397,119 @@ const expectEndedMountsStep = (...matchers) => (simulation) => {
415
397
  };
416
398
  /* eslint-enable @typescript-eslint/consistent-type-assertions */
417
399
  };
400
+ const applyExternalMessage = (simulation, message, context) => {
401
+ const internal = toInternal(simulation);
402
+ assertNoUnresolvedCommands(internal.commands, context);
403
+ assertNoUnresolvedMounts(internal.mounts, context);
404
+ assertNoUnacknowledgedUnmounts(unacknowledgedEndedMountsOf(internal.mountSlots), context);
405
+ /* eslint-disable @typescript-eslint/consistent-type-assertions */
406
+ const messageAsParent = message;
407
+ const result = internal.updateFn(internal.model, messageAsParent);
408
+ const [nextModel, commands] = result;
409
+ const outMessage = result.length === 3 ? result[2] : internal.outMessage;
410
+ return {
411
+ ...internal,
412
+ model: nextModel,
413
+ message: messageAsParent,
414
+ commands: Array.appendAll(internal.commands, commands),
415
+ outMessage,
416
+ };
417
+ /* eslint-enable @typescript-eslint/consistent-type-assertions */
418
+ };
419
+ /** Feeds a Message through update as if a Subscription had emitted it,
420
+ * then re-renders. Use it for Messages whose real cause is a Subscription
421
+ * (a timer tick, a WebSocket frame, a global listener), which have no
422
+ * element in the rendered tree to interact with. Do NOT reach for it when
423
+ * the Message has a DOM affordance: click the actual button instead, so
424
+ * the test exercises the handler wiring this step skips. Like an
425
+ * interaction, it throws if unresolved Commands, unresolved Mounts, or
426
+ * unacknowledged unmounts are pending. */
427
+ const emitSubscriptionMessage = (message) => (simulation) => applyExternalMessage(simulation, message, 'when a Subscription emitted a new Message');
428
+ const MANAGED_RESOURCE_CONTEXT = 'when a ManagedResource dispatched a new Message';
429
+ /** Declares that a ManagedResource's acquire succeeded, feeding the entry's
430
+ * `onAcquired` Message through update the way the runtime would. The step
431
+ * takes exactly the arguments the entry's `onAcquired` declares: a handler
432
+ * that consumes the acquired value needs one here, and a handler that
433
+ * ignores it needs none. Requires the current Model to request the
434
+ * resource: the runtime only acquires while `modelToMaybeRequirements`
435
+ * returns Some, so drive the Model into that state through real steps
436
+ * first. */
437
+ const acquireManagedResource = (entry, ...args) => (simulation) => {
438
+ const internal = toInternal(simulation);
439
+ const maybeRequirements = entry.modelToMaybeRequirements(internal.model);
440
+ if (Option.isNone(maybeRequirements)) {
441
+ throw new Error(`I tried to acquire the ManagedResource "${entry.resource.key}" but the current Model does not request it.\n\n` +
442
+ 'modelToMaybeRequirements returned None. The runtime only acquires while the Model requests the resource, so drive that transition through real steps first.');
443
+ }
444
+ return applyExternalMessage(simulation, entry.onAcquired(...args), MANAGED_RESOURCE_CONTEXT);
445
+ };
446
+ /** Declares that a ManagedResource's acquire failed, feeding the entry's
447
+ * `onAcquireError(error)` Message through update the way the runtime
448
+ * would. Requires the current Model to request the resource, the same as
449
+ * {@link acquireManagedResource}: the runtime only attempts acquisition
450
+ * while `modelToMaybeRequirements` returns Some. */
451
+ const failAcquireManagedResource = (entry, error) => (simulation) => {
452
+ const internal = toInternal(simulation);
453
+ const maybeRequirements = entry.modelToMaybeRequirements(internal.model);
454
+ if (Option.isNone(maybeRequirements)) {
455
+ throw new Error(`I tried to fail acquiring the ManagedResource "${entry.resource.key}" but the current Model does not request it.\n\n` +
456
+ 'modelToMaybeRequirements returned None. The runtime only attempts acquisition while the Model requests the resource, so drive that transition through real steps first.');
457
+ }
458
+ return applyExternalMessage(simulation, entry.onAcquireError(error), MANAGED_RESOURCE_CONTEXT);
459
+ };
460
+ /** Declares that a ManagedResource was released, feeding the entry's
461
+ * `onReleased()` Message through update. Models the runtime's Some to
462
+ * None transition, which releases and then dispatches `onReleased()`, so
463
+ * it requires the current Model to no longer request the resource: drive
464
+ * the Model out of the requesting state through real steps first. The
465
+ * runtime's Some to Some re-acquire (structurally changed requirements),
466
+ * which also dispatches `onReleased()` and then `onAcquired(value)` while
467
+ * the Model still requests the resource, has no step yet. */
468
+ const releaseManagedResource = (entry) => (simulation) => {
469
+ const internal = toInternal(simulation);
470
+ const maybeRequirements = entry.modelToMaybeRequirements(internal.model);
471
+ if (Option.isSome(maybeRequirements)) {
472
+ throw new Error(`I tried to release the ManagedResource "${entry.resource.key}" but the current Model still requests it.\n\n` +
473
+ 'modelToMaybeRequirements returned Some. This step models the Some to None transition, so drive the Model out of the requesting state through real steps first.');
474
+ }
475
+ return applyExternalMessage(simulation, entry.onReleased(), MANAGED_RESOURCE_CONTEXT);
476
+ };
477
+ /** Dispatches a CustomEvent a rendered custom element declares, feeding the
478
+ * Message its `On*` event mapping produces through update. The event name
479
+ * and detail are typed by the spec's event Schemas. The element must be in
480
+ * the rendered tree with the event's attribute attached, so the test
481
+ * exercises the same mapping the browser event would. */
482
+ const emitCustomElementEvent = (spec, target, eventName, detail) => (simulation) => {
483
+ if (!Object.hasOwn(spec.events, eventName)) {
484
+ const declared = Object.keys(spec.events).join(', ');
485
+ throw new Error(`I tried to emit "${eventName}" but the '${spec.tag}' element does not declare it.\n\n` +
486
+ `Declared events: ${String_.isEmpty(declared) ? '(none)' : declared}.`);
487
+ }
488
+ const internal = toInternal(simulation);
489
+ const scopedTarget = applyScopeToTarget(internal.scope, target);
490
+ const { maybeElement, description } = resolveTarget(internal.html, scopedTarget);
491
+ if (Option.isNone(maybeElement)) {
492
+ throw new Error(`I could not find an element matching ${description}.\n\n` +
493
+ 'Check that your selector matches an element in the current view.');
494
+ }
495
+ const element = maybeElement.value;
496
+ if (element.data?.on?.[eventName] === undefined) {
497
+ throw new Error(`I found an element matching ${description} but it has no ${eventName} handler.\n\n` +
498
+ `Make sure the element has the On${kebabToPascal(eventName)} attribute from its CustomElement builder.`);
499
+ }
500
+ // NOTE: the OnCustomEvent handler only dispatches when the event is a
501
+ // real CustomEvent instance, so the synthetic event must be constructed
502
+ // with `new CustomEvent(...)`, never a plain object literal like the
503
+ // other interaction helpers use. A None capture means nothing was
504
+ // dispatched, and since the handler dispatches unconditionally for a
505
+ // genuine CustomEvent, that can only be the instanceof check failing
506
+ // (a CustomEvent realm mismatch in the test environment).
507
+ const maybeNext = maybeCaptureFromElement(simulation, element, description, eventName, handler => {
508
+ handler(new CustomEvent(eventName, { detail }));
509
+ });
510
+ return Option.getOrThrowWith(maybeNext, () => new Error(`I dispatched "${eventName}" on the element matching ${description} but its handler produced no Message.\n\n` +
511
+ "The OnCustomEvent handler only dispatches for CustomEvent instances, so the synthetic event failed the runtime's instanceof check. This points to a CustomEvent realm mismatch in the test environment."));
512
+ };
418
513
  /** Steps that operate on the pending Commands of a scene simulation.
419
514
  * Destructure as `const { Command } = Scene` for concise call sites. */
420
515
  export const Command = {
@@ -450,6 +545,73 @@ export const Mount = {
450
545
  * every Mount that fires and then unmounts during a scene. */
451
546
  expectEnded: expectEndedMountsStep,
452
547
  };
548
+ /** Steps that model Messages arriving from a Subscription.
549
+ * Destructure as `const { Subscription } = Scene` for concise call sites. */
550
+ export const Subscription = {
551
+ /** Feeds a Message through update as if a Subscription had emitted it,
552
+ * then re-renders. Only for Messages whose real cause is a Subscription;
553
+ * if the Message has a DOM affordance, click it instead. */
554
+ emit: emitSubscriptionMessage,
555
+ };
556
+ /** Steps that model the lifecycle Messages of a ManagedResource. The test
557
+ * declares the lifecycle outcome the way `Scene.Command.resolve` declares a
558
+ * Command result, and each step checks the current Model against the
559
+ * entry's `modelToMaybeRequirements` gate first, mirroring the runtime's
560
+ * None to Some and Some to None transitions. The Some to Some re-acquire
561
+ * transition has no step yet. Destructure as
562
+ * `const { ManagedResource } = Scene` for concise call sites. */
563
+ export const ManagedResource = {
564
+ /** Declares a successful acquire, feeding the entry's `onAcquired` Message
565
+ * through update. Takes exactly the arguments `onAcquired` declares. The
566
+ * current Model must request the resource. */
567
+ acquire: acquireManagedResource,
568
+ /** Declares a failed acquire, feeding `onAcquireError(error)` through
569
+ * update. The current Model must request the resource. */
570
+ failAcquire: failAcquireManagedResource,
571
+ /** Declares a release, feeding `onReleased()` through update. The current
572
+ * Model must no longer request the resource. */
573
+ release: releaseManagedResource,
574
+ };
575
+ /** Steps that model CustomEvents arriving from a rendered custom element.
576
+ * Destructure as `const { CustomElement } = Scene` for concise call sites. */
577
+ export const CustomElement = {
578
+ /** Dispatches a declared CustomEvent through the element's event mapping.
579
+ * The event name and detail are typed by the spec's event Schemas. */
580
+ emit: emitCustomElementEvent,
581
+ };
582
+ /** Asserts that the OutMessage is Some with the expected value.
583
+ *
584
+ * The tracked OutMessage is the third element of the most recent update
585
+ * result that had one. An update branch that returns a two-tuple leaves
586
+ * the previous value latched in place, so keep every branch of an
587
+ * OutMessage-returning update on the three-tuple shape, returning
588
+ * `Option.none()` when there is nothing to report. */
589
+ export const expectOutMessage = (expected) => (simulation) => {
590
+ const internal = toInternal(simulation);
591
+ const outMessage = internal.outMessage;
592
+ if (!Option.isOption(outMessage) ||
593
+ Option.isNone(outMessage) ||
594
+ !Equal.equals(outMessage.value, expected)) {
595
+ throw new Error(`Expected OutMessage:\n\n Some(${JSON.stringify(expected)})\n\nBut got:\n\n ${JSON.stringify(outMessage)}`);
596
+ }
597
+ return simulation;
598
+ };
599
+ /** Asserts that the OutMessage is None.
600
+ *
601
+ * The tracked OutMessage is the third element of the most recent update
602
+ * result that had one. An update branch that returns a two-tuple leaves
603
+ * the previous value latched in place, so keep every branch of an
604
+ * OutMessage-returning update on the three-tuple shape, returning
605
+ * `Option.none()` when there is nothing to report. */
606
+ export const expectNoOutMessage = () => (simulation) => {
607
+ const internal = toInternal(simulation);
608
+ const outMessage = internal.outMessage;
609
+ if (!Predicate.isUndefined(outMessage) &&
610
+ !(Option.isOption(outMessage) && Option.isNone(outMessage))) {
611
+ throw new Error(`Expected no OutMessage but got:\n\n ${JSON.stringify(outMessage)}`);
612
+ }
613
+ return simulation;
614
+ };
453
615
  /** Runs a function for side effects (e.g. assertions) without breaking the step chain. */
454
616
  export const tap = (f) => (simulation) => {
455
617
  f(simulation);
@@ -960,6 +1122,24 @@ export const expectAll = (locatorAll) => ({
960
1122
  ...buildExpectAllChain(locatorAll, false),
961
1123
  not: buildExpectAllChain(locatorAll, true),
962
1124
  });
1125
+ // VIEW ADAPTERS
1126
+ /** Adapts a Submodel view that declares `ViewInputs` to the `(model, h)`
1127
+ * shape `Scene.scene` takes. `defaults` supplies the full `ViewInputs`
1128
+ * once; the returned factory accepts per-test overrides for everything
1129
+ * except `toView`, so tests vary value inputs while the renderer stays
1130
+ * pinned:
1131
+ *
1132
+ * ```ts
1133
+ * const sceneView = Scene.withViewInputs(view, {
1134
+ * value: 5,
1135
+ * toView: testToView,
1136
+ * })
1137
+ *
1138
+ * Scene.scene({ update, view: sceneView() }, ...)
1139
+ * Scene.scene({ update, view: sceneView({ isDisabled: true }) }, ...)
1140
+ * ```
1141
+ */
1142
+ export const withViewInputs = (view, defaults) => (overrides) => (model, h) => view(model, { ...defaults, ...overrides }, h);
963
1143
  // SCENE
964
1144
  /** Executes a scene test. Throws if any Commands remain unresolved. */
965
1145
  export const scene = (config, ...steps) => {
@@ -26,7 +26,7 @@ export type StorySimulation<Model, Message, OutMessage = undefined> = Readonly<{
26
26
  outMessage: OutMessage;
27
27
  }>;
28
28
  /** A callable step that sets the initial Model. Carries phantom type for compile-time validation. */
29
- export type WithStep<Model> = Readonly<{
29
+ export type GivenStep<Model> = Readonly<{
30
30
  _phantomModel: Model;
31
31
  }> & (<M, Message, OutMessage = undefined>(simulation: StorySimulation<M, Message, OutMessage>) => StorySimulation<M, Message, OutMessage>);
32
32
  /** A model-assertion step produced by {@link model}. */
@@ -34,12 +34,11 @@ export type ModelStep<Model> = Readonly<{
34
34
  readonly _tag: 'ModelStep';
35
35
  readonly assert: (model: Model) => void;
36
36
  }>;
37
- /** A single step in a story: a {@link WithStep}, a {@link ModelStep},
37
+ /** A single step in a story: a {@link GivenStep}, a {@link ModelStep},
38
38
  * or a simulation transform. */
39
- export type StoryStep<Model> = WithStep<NoInfer<Model>> | ModelStep<NoInfer<Model>> | ((sim: StorySimulation<any, any, any>) => StorySimulation<any, any, any>);
39
+ export type StoryStep<Model> = GivenStep<NoInfer<Model>> | ModelStep<NoInfer<Model>> | ((sim: StorySimulation<any, any, any>) => StorySimulation<any, any, any>);
40
40
  /** Sets the initial Model for a test story. */
41
- export { with_ as with };
42
- declare const with_: <Model>(model: Model) => WithStep<Model>;
41
+ export declare const given: <Model>(model: Model) => GivenStep<Model>;
43
42
  /** Sends a Message through update. Commands stay pending until resolve or
44
43
  * resolveAll. */
45
44
  export declare const message: <MessageInput>(message_: MessageInput) => <Model, Message, OutMessage>(simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>;
@@ -1 +1 @@
1
- {"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../src/test/story.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../src/test/story.ts"],"names":[],"mappings":"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"}
@@ -5,8 +5,7 @@ const toInternal = (simulation) =>
5
5
  simulation;
6
6
  // STEPS
7
7
  /** Sets the initial Model for a test story. */
8
- export { with_ as with };
9
- const with_ = (model) => {
8
+ export const given = (model) => {
10
9
  const step = (simulation) => {
11
10
  const internal = toInternal(simulation);
12
11
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foldkit",
3
- "version": "0.133.0",
3
+ "version": "0.135.0",
4
4
  "description": "A TypeScript frontend framework, built on Effect and architected like Elm",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",