@voltro/testing 0.83.1 → 0.85.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.
package/dist/client.d.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import { Effect } from 'effect';
2
2
  import { Exit } from 'effect/Exit';
3
+ import { Fiber } from 'effect/Fiber';
3
4
  import { FieldErrors } from '@voltro/client';
4
5
  import { FormBinding } from '@voltro/client';
5
6
  import { FormStateSnapshot } from '@voltro/client';
6
7
  import { ReactElement } from 'react';
7
8
  import { ReactNode } from 'react';
8
- import { RunForkOptions } from 'effect/Runtime';
9
- import { RuntimeFiber } from 'effect/Fiber';
10
9
  import { UseFormBindingOptions } from '@voltro/client';
11
10
 
12
11
  /** The snapshot shape `useConnectionStatus` subscribes to. */
@@ -38,13 +37,9 @@ declare interface ConnectionFacts {
38
37
  * starts calling goes red here instead of in whichever hook reaches it first.
39
38
  */
40
39
  export declare const FAKE_RUNTIME: {
41
- runPromise: <A, E>(effect: Effect.Effect<A, E, never>, options?: {
42
- readonly signal?: AbortSignal | undefined;
43
- } | undefined) => Promise<A>;
44
- runPromiseExit: <A, E>(effect: Effect.Effect<A, E, never>, options?: {
45
- readonly signal?: AbortSignal;
46
- } | undefined) => Promise< Exit<A, E>>;
47
- runFork: <A, E>(effect: Effect.Effect<A, E>, options?: RunForkOptions) => RuntimeFiber<A, E>;
40
+ runPromise: <A, E>(effect: Effect.Effect<A, E>, options?: Effect.RunOptions | undefined) => Promise<A>;
41
+ runPromiseExit: <A, E>(effect: Effect.Effect<A, E>, options?: Effect.RunOptions | undefined) => Promise< Exit<A, E>>;
42
+ runFork: <A, E>(effect: Effect.Effect<A, E, never>, options?: Effect.RunOptions | undefined) => Fiber<A, E>;
48
43
  dispose: () => Effect.Effect<void, never, never>;
49
44
  };
50
45
 
package/dist/client.js CHANGED
@@ -84,6 +84,9 @@ var o = async (e, r = {}) => {
84
84
  } };
85
85
  },
86
86
  autoApply: () => {},
87
+ hasIntent: () => !1,
88
+ rowsOf: () => [],
89
+ subscribeAny: () => () => {},
87
90
  revertByMutation: () => {},
88
91
  confirmByMutation: () => {},
89
92
  update: () => {},
@@ -104,7 +107,8 @@ var o = async (e, r = {}) => {
104
107
  _.delete(e);
105
108
  }),
106
109
  getSnapshot: () => g,
107
- reportExternalSuccess: () => {}
110
+ reportExternalSuccess: () => {},
111
+ subjectSignal: new AbortController().signal
108
112
  }, y = {}, b = (t, n, r) => {
109
113
  let i = t.split("."), a = y;
110
114
  for (let e of i.slice(0, -1)) a[e] = a[e] ?? {}, a = a[e];
package/dist/crdt.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { CrdtBackend } from '@voltro/local-first';
2
+
3
+ /** Register the conformance suite with vitest. */
4
+ export declare const crdtBackendConformance: (name: string, options: CrdtBackendConformanceOptions) => void;
5
+
6
+ export declare interface CrdtBackendConformanceOptions {
7
+ /** The backend under test. */
8
+ readonly backend: CrdtBackend;
9
+ }
10
+
11
+ export { }
package/dist/crdt.js ADDED
@@ -0,0 +1,77 @@
1
+ import { describe as e, expect as t, it as n } from "vitest";
2
+ //#region src/crdtBackendConformance.ts
3
+ var r = (r, i) => {
4
+ let a = i.backend, o = (e) => a.createText(e).encodeState(), s = (e, t, n) => {
5
+ let r = a.createText();
6
+ return r.applyState(e), r.insert(t, n), r.encodeState();
7
+ };
8
+ e(`crdt backend conformance — ${r}`, () => {
9
+ n("merge: commutative, idempotent, empty state is the identity", () => {
10
+ let e = o("base"), n = s(e, 0, "X"), r = s(e, 4, "Y");
11
+ t(a.decodeText(a.merge(n, r))).toBe(a.decodeText(a.merge(r, n))), t(a.decodeText(a.merge(a.merge(n, r), n))).toBe(a.decodeText(a.merge(n, r))), t(a.decodeText(a.merge(a.emptyState(), n))).toBe(a.decodeText(n)), t(a.decodeText(a.emptyState())).toBe("");
12
+ }), n("text handles converge under concurrent edits; undo reverts only their own edits", () => {
13
+ let e = o("ab"), n = a.createText(void 0, { undoCaptureMs: 0 });
14
+ n.applyState(e), t(n.canUndo()).toBe(!1), n.insert(1, "1");
15
+ let r = s(e, 2, "2");
16
+ n.applyState(r), t(n.toString()).toBe(a.decodeText(a.merge(s(e, 1, "1"), r))), t(n.undo()).toBe(!0), t(n.toString()).toBe(a.decodeText(r)), t(n.redo()).toBe(!0), t(n.toString()).toContain("1");
17
+ }), n("doc handles: folds are reported as remote, own edits as local; incremental updates apply", () => {
18
+ let e = a.createDoc(), n = [];
19
+ e.onUpdate((e, t) => {
20
+ n.push(t.local);
21
+ }), e.applyState(o("remote")), a.counterAdd(e, 1), t(n).toEqual([!1, !0]);
22
+ let r = a.createDoc(e.encodeState()), i = r.stateVector();
23
+ a.counterAdd(e, 2), r.applyState(e.encodeUpdateSince(i)), t(a.counterValue(r.encodeState())).toBe(3), t(e.epoch()).toBeUndefined();
24
+ }), n("local updates coalesce without a base: merging two queued edits loses neither", () => {
25
+ let e = a.createDoc();
26
+ a.counterAdd(e, 5);
27
+ let n = e.encodeState(), r = a.createDoc(n), i = [];
28
+ r.onUpdate((e, t) => {
29
+ t.local && i.push(e);
30
+ }), a.counterAdd(r, 1), a.counterAdd(r, 2);
31
+ let o = a.merge(i[0], i[1]);
32
+ t(a.counterValue(a.merge(n, o))).toBe(8);
33
+ }), n("compact keeps the content and still merges with the old lineage", () => {
34
+ let e = s(s(o("seed"), 4, "!"), 0, ">"), n = a.compact(e);
35
+ t(a.decodeText(n)).toBe(a.decodeText(e)), t(a.decodeText(a.merge(n, e))).toBe(a.decodeText(e));
36
+ }), n("restoreTo is an edit on the current lineage that merges with concurrent edits", () => {
37
+ let e = o("version one"), n = s(e, 11, " and more"), r = a.restoreTo(n, e);
38
+ t(a.decodeText(a.merge(n, r))).toBe("version one");
39
+ let i = s(n, 0, "# ");
40
+ t(a.decodeText(a.merge(a.merge(n, i), r))).toContain("version one");
41
+ }), n("rebase keeps the content, stamps the epoch and shares no author with the old lineage", () => {
42
+ let e = s(o("kept"), 4, "."), n = a.rebase(e, "epoch-x");
43
+ t(a.decodeText(n)).toBe("kept."), t(a.epochOf(n)).toBe("epoch-x"), t(a.epochOf(e)).toBeUndefined();
44
+ let r = a.authorsOf(e);
45
+ t([...a.authorsOf(n)].some((e) => r.has(e))).toBe(!1);
46
+ }), n("translate carries a text edit made on an archived lineage over to the current one", () => {
47
+ let e = o("shared text"), n = s(e, 11, " + offline"), r = a.rebase(s(e, 0, "> "), "e1"), i = a.translate(e, n, r);
48
+ t(i).toBeDefined(), t(a.decodeText(a.merge(r, i))).toBe("> shared text + offline");
49
+ }), n("the content schema version is recorded, travels with the state and survives a rebase", () => {
50
+ let e = a.createDoc(o("content"));
51
+ t(e.schemaVersion()).toBe(0), e.setSchemaVersion(3);
52
+ let n = e.encodeState();
53
+ t(a.createDoc(n).schemaVersion()).toBe(3);
54
+ let r = a.createDoc(a.rebase(n, "e2"));
55
+ t(r.schemaVersion()).toBe(3), t(a.decodeText(r.encodeState())).toBe("content");
56
+ }), n("an increment over a delivered state merges into it; over a state that lacks its base it is refused or reported", () => {
57
+ let e = o("base"), n = a.createDoc(s(e, 4, "!")).encodeUpdateSince(a.createDoc(e).stateVector());
58
+ t(a.decodeText(a.merge(e, n))).toBe("base!");
59
+ let r = !1;
60
+ try {
61
+ let e = a.merge(a.emptyState(), n);
62
+ r = a.missingDependencies?.(e) === !0;
63
+ } catch {
64
+ r = !0;
65
+ }
66
+ t(r).toBe(!0);
67
+ }), n("carryReplaced, when implemented, carries nothing for content no migration replaced", () => {
68
+ let e = o("kept as is");
69
+ t(a.carryReplaced?.(e, s(e, 4, "!"))).toBeUndefined(), t(a.carryReplaced?.(a.emptyState(), e)).toBeUndefined();
70
+ }), n("counter steps from different writers commute", () => {
71
+ let e = a.createDoc(), n = a.createDoc();
72
+ a.counterAdd(e, 5), a.counterAdd(n, -2), a.counterAdd(e, 1), t(a.counterValue(a.merge(e.encodeState(), n.encodeState()))).toBe(4), t(a.counterValue(a.merge(n.encodeState(), e.encodeState()))).toBe(4), t(a.counterValue(a.emptyState())).toBe(0);
73
+ });
74
+ });
75
+ };
76
+ //#endregion
77
+ export { r as crdtBackendConformance };
package/dist/dialect.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { applySchema } from '@voltro/database/sql';
2
2
  import { DataStore } from '@voltro/database';
3
3
  import { Effect } from 'effect';
4
- import { SqlClient } from '@effect/sql';
4
+ import { SqlClient } from 'effect/sql';
5
5
  import { SqlDialect } from '@voltro/database';
6
6
 
7
7
  export { applySchema }