@evolu/common 8.15.0 → 8.16.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/src/Console.d.ts +24 -46
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +34 -29
- package/dist/src/Error.d.ts +10 -6
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +52 -20
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +16 -12
- package/dist/src/Task.d.ts +3 -1
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +15 -13
- package/dist/src/Worker.d.ts +3 -0
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +6 -1
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +7 -7
- package/dist/src/local-first/Evolu.d.ts +4 -0
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +3 -0
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +9 -5
- package/dist/src/local-first/Shared.d.ts +55 -39
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +264 -320
- package/package.json +1 -1
- package/src/Console.test.ts +75 -247
- package/src/Console.ts +68 -110
- package/src/Error.test.ts +85 -0
- package/src/Error.ts +48 -22
- package/src/Sqlite.ts +19 -11
- package/src/Task.test.ts +46 -0
- package/src/Task.ts +17 -13
- package/src/Worker.ts +6 -1
- package/src/local-first/Db.ts +12 -8
- package/src/local-first/Evolu.ts +4 -0
- package/src/local-first/Schema.test.ts +80 -1
- package/src/local-first/Schema.ts +15 -5
- package/src/local-first/Shared.test.ts +414 -39
- package/src/local-first/Shared.ts +386 -440
package/package.json
CHANGED
package/src/Console.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, it
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
2
|
import {
|
|
3
3
|
assertEqual,
|
|
4
4
|
assertFalse,
|
|
@@ -114,19 +114,35 @@ describe("createConsole", () => {
|
|
|
114
114
|
);
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
it("child
|
|
117
|
+
it("child without own level follows its parent's level", () => {
|
|
118
118
|
const output = createTestOutput();
|
|
119
119
|
const console = createConsole({ output, level: "info" });
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
// Child inherits "info" level
|
|
123
|
-
child.debug("ignored");
|
|
124
|
-
child.info("logged");
|
|
120
|
+
const grandchild = console.child("relay").child("db");
|
|
125
121
|
|
|
126
|
-
|
|
122
|
+
grandchild.debug("ignored");
|
|
127
123
|
console.setLevel("debug");
|
|
128
|
-
|
|
124
|
+
grandchild.debug("logged");
|
|
129
125
|
|
|
126
|
+
assertEqual(grandchild.getLevel(), "debug");
|
|
127
|
+
assertFalse(grandchild.hasOwnLevel());
|
|
128
|
+
assertEqual(
|
|
129
|
+
output.entries.map((e) => e.entry.args[0]),
|
|
130
|
+
["logged"],
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("grandchild follows its parent's own level", () => {
|
|
135
|
+
const output = createTestOutput();
|
|
136
|
+
const console = createConsole({ output, level: "info" });
|
|
137
|
+
const relay = console.child("relay");
|
|
138
|
+
const db = relay.child("db");
|
|
139
|
+
|
|
140
|
+
relay.setLevel("debug");
|
|
141
|
+
db.debug("logged");
|
|
142
|
+
assertEqual(db.getLevel(), "debug");
|
|
143
|
+
|
|
144
|
+
relay.setLevel(null);
|
|
145
|
+
assertEqual(db.getLevel(), "info");
|
|
130
146
|
assertEqual(
|
|
131
147
|
output.entries.map((e) => e.entry.args[0]),
|
|
132
148
|
["logged"],
|
|
@@ -139,9 +155,9 @@ describe("createConsole", () => {
|
|
|
139
155
|
const child = console.child("relay");
|
|
140
156
|
|
|
141
157
|
child.setLevel("debug");
|
|
158
|
+
console.setLevel("error");
|
|
142
159
|
child.debug("logged");
|
|
143
|
-
|
|
144
|
-
console.debug("ignored");
|
|
160
|
+
console.warn("ignored");
|
|
145
161
|
|
|
146
162
|
assertEqual(
|
|
147
163
|
output.entries.map((e) => e.entry.args[0]),
|
|
@@ -160,6 +176,9 @@ describe("createConsole", () => {
|
|
|
160
176
|
child.setLevel(null);
|
|
161
177
|
assertFalse(child.hasOwnLevel());
|
|
162
178
|
assertEqual(child.getLevel(), "info");
|
|
179
|
+
|
|
180
|
+
console.setLevel("warn");
|
|
181
|
+
assertEqual(child.getLevel(), "warn");
|
|
163
182
|
});
|
|
164
183
|
|
|
165
184
|
it("child adds path", () => {
|
|
@@ -186,89 +205,19 @@ describe("createConsole", () => {
|
|
|
186
205
|
assertEqual(output.entries[0].formattedArgs, ["prefix", "message"]);
|
|
187
206
|
});
|
|
188
207
|
|
|
189
|
-
it("
|
|
208
|
+
it("write filters replayed entries by level", () => {
|
|
190
209
|
const output = createTestOutput();
|
|
191
|
-
const console = createConsole({
|
|
192
|
-
output,
|
|
193
|
-
level: "log",
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
console.time("timer");
|
|
197
|
-
console.timeLog("timer");
|
|
198
|
-
console.timeEnd("timer");
|
|
199
|
-
console.dir({ foo: 1 });
|
|
200
|
-
console.table([1, 2, 3]);
|
|
201
|
-
console.count("counter");
|
|
202
|
-
console.countReset("counter");
|
|
203
|
-
|
|
204
|
-
assertLength(output.entries, 0);
|
|
205
|
-
|
|
206
|
-
console.setLevel("debug");
|
|
210
|
+
const console = createConsole({ output, level: "info" });
|
|
207
211
|
|
|
208
|
-
console.
|
|
209
|
-
console.
|
|
212
|
+
console.write({ method: "debug", path: ["worker"], args: ["dropped"] });
|
|
213
|
+
console.write({ method: "error", path: ["worker"], args: ["replayed"] });
|
|
210
214
|
|
|
211
215
|
assertEqual(
|
|
212
|
-
output.entries.map((e) => e.entry.
|
|
213
|
-
["
|
|
216
|
+
output.entries.map((e) => e.entry.args[0]),
|
|
217
|
+
["replayed"],
|
|
214
218
|
);
|
|
215
219
|
});
|
|
216
220
|
|
|
217
|
-
it("debug-level methods skip formatter", () => {
|
|
218
|
-
const output = createTestOutput();
|
|
219
|
-
const formatter = mock.fn((entry: ConsoleEntry) => [
|
|
220
|
-
"formatted",
|
|
221
|
-
...entry.args,
|
|
222
|
-
]);
|
|
223
|
-
const console = createConsole({
|
|
224
|
-
output,
|
|
225
|
-
level: "debug",
|
|
226
|
-
formatter,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
console.info("info message");
|
|
230
|
-
console.dir({ foo: 1 });
|
|
231
|
-
|
|
232
|
-
assertEqual(output.entries[0].formattedArgs, ["formatted", "info message"]);
|
|
233
|
-
assertEqual(output.entries[1].formattedArgs, [{ foo: 1 }]);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it("children tracking", () => {
|
|
237
|
-
const console = createConsole();
|
|
238
|
-
const child1 = console.child("a");
|
|
239
|
-
const child2 = console.child("b");
|
|
240
|
-
const grandchild = child1.child("c");
|
|
241
|
-
|
|
242
|
-
assertEqual(console.children.size, 2);
|
|
243
|
-
assertTrue(console.children.has(child1));
|
|
244
|
-
assertTrue(console.children.has(child2));
|
|
245
|
-
assertEqual(child1.children.size, 1);
|
|
246
|
-
assertTrue(child1.children.has(grandchild));
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
it("name property", () => {
|
|
250
|
-
const console = createConsole({ name: "root" });
|
|
251
|
-
const child = console.child("relay");
|
|
252
|
-
|
|
253
|
-
assertEqual(console.name, "root");
|
|
254
|
-
assertEqual(child.name, "relay");
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
it("write bypasses level filtering", () => {
|
|
258
|
-
const output = createTestOutput();
|
|
259
|
-
const console = createConsole({ output, level: "silent" });
|
|
260
|
-
|
|
261
|
-
const entry: ConsoleEntry = {
|
|
262
|
-
method: "debug",
|
|
263
|
-
path: ["worker"],
|
|
264
|
-
args: ["replayed"],
|
|
265
|
-
};
|
|
266
|
-
console.write(entry);
|
|
267
|
-
|
|
268
|
-
assertLength(output.entries, 1);
|
|
269
|
-
assertEqual(output.entries[0].entry, entry);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
221
|
it("write passes formatter to output", () => {
|
|
273
222
|
const output = createTestOutput();
|
|
274
223
|
const formatter = (entry: ConsoleEntry) => ["fmt", ...entry.args];
|
|
@@ -303,6 +252,18 @@ describe("createNativeConsoleOutput", () => {
|
|
|
303
252
|
assertSame(logSpy.mock.calls[0].this, nativeConsole);
|
|
304
253
|
});
|
|
305
254
|
|
|
255
|
+
it("writes trace entries with native debug", (t) => {
|
|
256
|
+
const debugSpy = t.mock.method(nativeConsole, "debug", () => undefined);
|
|
257
|
+
const traceSpy = t.mock.method(nativeConsole, "trace", () => undefined);
|
|
258
|
+
const output = createNativeConsoleOutput();
|
|
259
|
+
|
|
260
|
+
output.write({ method: "trace", path: [], args: ["query"] });
|
|
261
|
+
|
|
262
|
+
assertEqual(debugSpy.mock.calls[0].arguments, ["query"]);
|
|
263
|
+
assertSame(debugSpy.mock.calls[0].this, nativeConsole);
|
|
264
|
+
assertLength(traceSpy.mock.calls, 0);
|
|
265
|
+
});
|
|
266
|
+
|
|
306
267
|
it("applies formatter", (t) => {
|
|
307
268
|
const logSpy = t.mock.method(nativeConsole, "info", () => undefined);
|
|
308
269
|
const output = createNativeConsoleOutput();
|
|
@@ -426,7 +387,7 @@ describe("createConsoleFormatter", () => {
|
|
|
426
387
|
|
|
427
388
|
it("absolute timestamp", () => {
|
|
428
389
|
const time = testCreateTime({
|
|
429
|
-
startAt: Date
|
|
390
|
+
startAt: new Date(2026, 0, 28, 14, 30, 15, 123).getTime() as Millis,
|
|
430
391
|
});
|
|
431
392
|
const formatter = createConsoleFormatter({ time })({
|
|
432
393
|
timestampFormat: "absolute",
|
|
@@ -438,13 +399,23 @@ describe("createConsoleFormatter", () => {
|
|
|
438
399
|
args: ["message"],
|
|
439
400
|
};
|
|
440
401
|
|
|
441
|
-
|
|
402
|
+
assertEqual(formatter(entry), ["14:30:15.123", "message"]);
|
|
403
|
+
});
|
|
442
404
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
405
|
+
it("relative timestamp is never negative", () => {
|
|
406
|
+
const time = testCreateTime({ startAt: 1000 as Millis });
|
|
407
|
+
const formatter = createConsoleFormatter({ time })({
|
|
408
|
+
timestampFormat: "relative",
|
|
409
|
+
startTime: 1500 as Millis,
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
const entry: ConsoleEntry = {
|
|
413
|
+
method: "info",
|
|
414
|
+
path: [],
|
|
415
|
+
args: ["message"],
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
assertEqual(formatter(entry), ["+0.000s", "message"]);
|
|
448
419
|
});
|
|
449
420
|
|
|
450
421
|
it("combines timestamp and path", () => {
|
|
@@ -462,61 +433,6 @@ describe("createConsoleFormatter", () => {
|
|
|
462
433
|
|
|
463
434
|
assertEqual(result, ["+0.000s [relay]", "message"]);
|
|
464
435
|
});
|
|
465
|
-
|
|
466
|
-
it("createConsoleFormatter example", () => {
|
|
467
|
-
const time = testCreateTime({ startAt: 0 as Millis });
|
|
468
|
-
const output = createTestOutput();
|
|
469
|
-
|
|
470
|
-
// Relative timestamps
|
|
471
|
-
const root = createConsole({
|
|
472
|
-
output,
|
|
473
|
-
formatter: createConsoleFormatter({ time })({
|
|
474
|
-
timestampFormat: "relative",
|
|
475
|
-
}),
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
const relay = root.child("relay");
|
|
479
|
-
relay.log("connected");
|
|
480
|
-
time.advance("1.5s");
|
|
481
|
-
relay.log("synced");
|
|
482
|
-
|
|
483
|
-
assertEqual(
|
|
484
|
-
output.entries.map((entry) => entry.formattedArgs),
|
|
485
|
-
[
|
|
486
|
-
["+0.000s [relay]", "connected"],
|
|
487
|
-
["+1.500s [relay]", "synced"],
|
|
488
|
-
],
|
|
489
|
-
);
|
|
490
|
-
|
|
491
|
-
// Nested children
|
|
492
|
-
const db = relay.child("db");
|
|
493
|
-
db.log("opened");
|
|
494
|
-
|
|
495
|
-
assertEqual(output.entries[2].formattedArgs, [
|
|
496
|
-
"+1.500s [relay] [db]",
|
|
497
|
-
"opened",
|
|
498
|
-
]);
|
|
499
|
-
|
|
500
|
-
// Absolute timestamps (local clock time HH:MM:SS.mmm)
|
|
501
|
-
const absoluteOutput = createTestOutput();
|
|
502
|
-
const absoluteTime = testCreateTime({
|
|
503
|
-
startAt: Date.UTC(2026, 0, 28, 14, 30, 15, 123) as Millis,
|
|
504
|
-
});
|
|
505
|
-
const absoluteRoot = createConsole({
|
|
506
|
-
output: absoluteOutput,
|
|
507
|
-
formatter: createConsoleFormatter({ time: absoluteTime })({
|
|
508
|
-
timestampFormat: "absolute",
|
|
509
|
-
}),
|
|
510
|
-
});
|
|
511
|
-
const absoluteRelay = absoluteRoot.child("relay");
|
|
512
|
-
|
|
513
|
-
absoluteRelay.log("connected");
|
|
514
|
-
|
|
515
|
-
const [timestamp, message] = absoluteOutput.entries[0].formattedArgs;
|
|
516
|
-
assertType(String, timestamp);
|
|
517
|
-
assertTrue(/^\d{2}:\d{2}:\d{2}\.\d{3} \[relay\]$/u.test(timestamp));
|
|
518
|
-
assertEqual(message, "connected");
|
|
519
|
-
});
|
|
520
436
|
});
|
|
521
437
|
|
|
522
438
|
describe("createConsoleStoreOutput", () => {
|
|
@@ -635,19 +551,18 @@ describe("createMultiOutput", () => {
|
|
|
635
551
|
assertEqual(entries1[0], entries2[0]);
|
|
636
552
|
});
|
|
637
553
|
|
|
638
|
-
it("
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
const console = createConsole({ output });
|
|
554
|
+
it("passes the formatter to each output", () => {
|
|
555
|
+
const first = createTestOutput();
|
|
556
|
+
const second = createTestOutput();
|
|
557
|
+
const console = createConsole({
|
|
558
|
+
output: createMultiOutput([first, second]),
|
|
559
|
+
formatter: (entry) => ["fmt", ...entry.args],
|
|
560
|
+
});
|
|
646
561
|
|
|
647
|
-
console.
|
|
562
|
+
console.info("msg");
|
|
648
563
|
|
|
649
|
-
|
|
650
|
-
assertEqual(
|
|
564
|
+
assertEqual(first.entries[0].formattedArgs, ["fmt", "msg"]);
|
|
565
|
+
assertEqual(second.entries[0].formattedArgs, ["fmt", "msg"]);
|
|
651
566
|
});
|
|
652
567
|
});
|
|
653
568
|
|
|
@@ -719,91 +634,4 @@ describe("testCreateConsole", () => {
|
|
|
719
634
|
|
|
720
635
|
assertEqual(console.getEntriesSnapshot()[0].path, ["relay", "db"]);
|
|
721
636
|
});
|
|
722
|
-
|
|
723
|
-
it("child inherits level at creation (static)", () => {
|
|
724
|
-
const console = testCreateConsole({ level: "info" });
|
|
725
|
-
const child = console.child("relay");
|
|
726
|
-
|
|
727
|
-
// Child inherits "info" level
|
|
728
|
-
child.debug("ignored");
|
|
729
|
-
child.info("logged");
|
|
730
|
-
|
|
731
|
-
// Parent change doesn't affect child
|
|
732
|
-
console.setLevel("debug");
|
|
733
|
-
child.debug("still ignored");
|
|
734
|
-
|
|
735
|
-
assertEqual(
|
|
736
|
-
console.getEntriesSnapshot().map((e) => e.args[0]),
|
|
737
|
-
["logged"],
|
|
738
|
-
);
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
it("child can override level independently", () => {
|
|
742
|
-
const console = testCreateConsole({ level: "info" });
|
|
743
|
-
const child = console.child("relay");
|
|
744
|
-
|
|
745
|
-
child.setLevel("debug");
|
|
746
|
-
child.debug("logged");
|
|
747
|
-
|
|
748
|
-
assertEqual(
|
|
749
|
-
console.getEntriesSnapshot().map((e) => e.args[0]),
|
|
750
|
-
["logged"],
|
|
751
|
-
);
|
|
752
|
-
});
|
|
753
|
-
|
|
754
|
-
it("hasOwnLevel tracks level override", () => {
|
|
755
|
-
const console = testCreateConsole({ level: "info" });
|
|
756
|
-
|
|
757
|
-
assertFalse(console.hasOwnLevel());
|
|
758
|
-
|
|
759
|
-
console.setLevel("debug");
|
|
760
|
-
assertTrue(console.hasOwnLevel());
|
|
761
|
-
|
|
762
|
-
console.setLevel(null);
|
|
763
|
-
assertFalse(console.hasOwnLevel());
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
it("debug-level methods use debug level", () => {
|
|
767
|
-
const console = testCreateConsole({ level: "log" });
|
|
768
|
-
|
|
769
|
-
console.time("timer");
|
|
770
|
-
console.dir({ foo: 1 });
|
|
771
|
-
console.table([1, 2]);
|
|
772
|
-
console.count("counter");
|
|
773
|
-
|
|
774
|
-
assertLength(console.getEntriesSnapshot(), 0);
|
|
775
|
-
|
|
776
|
-
console.setLevel("debug");
|
|
777
|
-
|
|
778
|
-
console.time("timer");
|
|
779
|
-
console.timeLog("timer", "extra");
|
|
780
|
-
console.timeEnd("timer");
|
|
781
|
-
console.dir({ foo: 1 });
|
|
782
|
-
console.table([1, 2]);
|
|
783
|
-
console.count("counter");
|
|
784
|
-
console.countReset("counter");
|
|
785
|
-
|
|
786
|
-
assertEqual(
|
|
787
|
-
console.getEntriesSnapshot().map((e) => e.method),
|
|
788
|
-
["time", "timeLog", "timeEnd", "dir", "table", "count", "countReset"],
|
|
789
|
-
);
|
|
790
|
-
});
|
|
791
|
-
|
|
792
|
-
it("children tracking", () => {
|
|
793
|
-
const console = testCreateConsole();
|
|
794
|
-
const child1 = console.child("a");
|
|
795
|
-
const child2 = console.child("b");
|
|
796
|
-
|
|
797
|
-
assertEqual(console.children.size, 2);
|
|
798
|
-
assertTrue(console.children.has(child1));
|
|
799
|
-
assertTrue(console.children.has(child2));
|
|
800
|
-
});
|
|
801
|
-
|
|
802
|
-
it("name property", () => {
|
|
803
|
-
const console = testCreateConsole();
|
|
804
|
-
const child = console.child("relay");
|
|
805
|
-
|
|
806
|
-
assertEqual(console.name, "");
|
|
807
|
-
assertEqual(child.name, "relay");
|
|
808
|
-
});
|
|
809
637
|
});
|