@evolu/common 8.0.0-next.4 → 8.0.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/Array.d.ts +279 -173
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +105 -101
- package/dist/src/Assert.d.ts +44 -44
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +44 -32
- package/dist/src/BigInt.d.ts +6 -3
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -2
- package/dist/src/Brand.d.ts +27 -40
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Buffer.d.ts +27 -11
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +9 -4
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +30 -19
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +145 -66
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +91 -43
- package/dist/src/Crypto.d.ts +85 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +44 -20
- package/dist/src/Eq.d.ts +87 -21
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +67 -19
- package/dist/src/Error.d.ts +5 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +16 -0
- package/dist/src/Function.d.ts +119 -58
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +86 -43
- package/dist/src/Http.d.ts +394 -0
- package/dist/src/Http.d.ts.map +1 -0
- package/dist/src/Http.js +102 -0
- package/dist/src/Identicon.d.ts +16 -7
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +14 -5
- package/dist/src/LeakDetector.d.ts +88 -0
- package/dist/src/LeakDetector.d.ts.map +1 -0
- package/dist/src/LeakDetector.js +86 -0
- package/dist/src/LockManager.d.ts +18 -9
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/LockManager.js +7 -8
- package/dist/src/Lookup.d.ts +43 -13
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +28 -8
- package/dist/src/Microtask.d.ts +1 -1
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +3 -7
- package/dist/src/Number.d.ts +49 -13
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +34 -5
- package/dist/src/Object.d.ts +160 -40
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +92 -46
- package/dist/src/Option.d.ts +10 -7
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +9 -6
- package/dist/src/Order.d.ts +21 -21
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +18 -21
- package/dist/src/Platform.d.ts +31 -0
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +98 -0
- package/dist/src/Random.d.ts +32 -17
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +12 -8
- package/dist/src/Redacted.d.ts +43 -29
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +14 -3
- package/dist/src/Ref.d.ts +11 -3
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +2 -2
- package/dist/src/RefCount.d.ts +2 -6
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +33 -90
- package/dist/src/Relation.d.ts +70 -5
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +77 -2
- package/dist/src/Resource.d.ts +590 -155
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +592 -343
- package/dist/src/Result.d.ts +838 -191
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +163 -102
- package/dist/src/Schedule.d.ts +684 -231
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +766 -295
- package/dist/src/Set.d.ts +89 -40
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +50 -29
- package/dist/src/Sqlite.d.ts +29 -72
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +41 -46
- package/dist/src/StackTrace.d.ts +40 -0
- package/dist/src/StackTrace.d.ts.map +1 -0
- package/dist/src/StackTrace.js +140 -0
- package/dist/src/Store.d.ts +5 -4
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +5 -4
- package/dist/src/String.d.ts +7 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +20 -7
- package/dist/src/Task.d.ts +3572 -1770
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1879 -1274
- package/dist/src/Test.d.ts +17 -125
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +17 -68
- package/dist/src/Time.d.ts +108 -49
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +172 -73
- package/dist/src/Type.d.ts +3542 -1926
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3070 -1784
- package/dist/src/Types.d.ts +200 -108
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +39 -8
- package/dist/src/WebSocket.d.ts +48 -23
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +15 -6
- package/dist/src/Worker.d.ts +94 -36
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +58 -24
- package/dist/src/index.d.ts +55 -52
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/cs.d.ts +94 -0
- package/dist/src/intl/cs.d.ts.map +1 -0
- package/dist/src/intl/cs.js +220 -0
- package/dist/src/intl/index.d.ts +7 -0
- package/dist/src/intl/index.d.ts.map +1 -0
- package/dist/src/intl/index.js +6 -0
- package/dist/src/local-first/Db.d.ts +12 -8
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +109 -132
- package/dist/src/local-first/Error.d.ts +4 -4
- package/dist/src/local-first/Evolu.d.ts +338 -92
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +47 -55
- package/dist/src/local-first/LocalAuth.d.ts +4 -4
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +61 -24
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +45 -8
- package/dist/src/local-first/Protocol.d.ts +44 -31
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +36 -13
- package/dist/src/local-first/Query.d.ts +147 -62
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +112 -58
- package/dist/src/local-first/Relay.d.ts +44 -14
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +92 -41
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +25 -8
- package/dist/src/local-first/Shared.d.ts +23 -21
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +100 -57
- package/dist/src/local-first/Storage.d.ts +53 -32
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +194 -234
- package/dist/src/local-first/Timestamp.d.ts +21 -21
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +2 -2
- package/dist/src/local-first/index.d.ts +11 -11
- package/package.json +14 -13
- package/src/Array.ts +306 -205
- package/src/Assert.ts +54 -69
- package/src/BigInt.ts +6 -3
- package/src/Brand.ts +27 -40
- package/src/Buffer.ts +28 -12
- package/src/Cache.ts +9 -4
- package/src/Callbacks.ts +30 -19
- package/src/Console.ts +156 -84
- package/src/Crypto.ts +83 -41
- package/src/Eq.ts +95 -22
- package/src/Error.ts +8 -4
- package/src/Function.ts +167 -59
- package/src/Http.ts +549 -0
- package/src/Identicon.ts +16 -7
- package/src/LeakDetector.ts +182 -0
- package/src/LockManager.ts +43 -39
- package/src/Lookup.ts +62 -28
- package/src/Microtask.ts +19 -23
- package/src/Number.ts +64 -12
- package/src/Object.ts +173 -49
- package/src/Option.ts +10 -7
- package/src/Order.ts +23 -21
- package/src/Platform.ts +136 -0
- package/src/Polyfills.ts +6 -12
- package/src/Random.ts +32 -19
- package/src/Redacted.ts +44 -30
- package/src/Ref.ts +14 -6
- package/src/RefCount.ts +38 -80
- package/src/Relation.ts +202 -10
- package/src/Resource.ts +1199 -591
- package/src/Result.ts +930 -271
- package/src/Schedule.ts +859 -343
- package/src/Set.ts +89 -40
- package/src/Sqlite.ts +144 -138
- package/src/StackTrace.ts +230 -0
- package/src/Store.ts +8 -7
- package/src/String.ts +22 -5
- package/src/Task.ts +5101 -2832
- package/src/Test.ts +20 -168
- package/src/Time.ts +293 -90
- package/src/Type.ts +10034 -4117
- package/src/Types.ts +227 -110
- package/src/WebSocket.ts +64 -36
- package/src/Worker.ts +180 -72
- package/src/index.ts +55 -52
- package/src/intl/cs.ts +388 -0
- package/src/intl/index.ts +7 -0
- package/src/local-first/Db.ts +152 -179
- package/src/local-first/Error.ts +4 -4
- package/src/local-first/Evolu.ts +495 -250
- package/src/local-first/LocalAuth.ts +6 -12
- package/src/local-first/Owner.ts +58 -21
- package/src/local-first/Protocol.ts +49 -31
- package/src/local-first/Query.ts +146 -61
- package/src/local-first/Relay.ts +51 -21
- package/src/local-first/Schema.ts +109 -51
- package/src/local-first/Shared.ts +266 -226
- package/src/local-first/Storage.ts +266 -264
- package/src/local-first/Timestamp.ts +25 -18
- package/src/local-first/index.ts +11 -11
- package/dist/src/Skiplist.d.ts +0 -28
- package/dist/src/Skiplist.d.ts.map +0 -1
- package/dist/src/Skiplist.js +0 -64
- package/dist/src/Tracer.d.ts +0 -48
- package/dist/src/Tracer.d.ts.map +0 -1
- package/dist/src/Tracer.js +0 -6
- package/src/Skiplist.ts +0 -108
- package/src/Tracer.ts +0 -54
package/dist/src/Sqlite.js
CHANGED
|
@@ -55,12 +55,12 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
55
55
|
var e = new Error(message);
|
|
56
56
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
57
|
});
|
|
58
|
-
import { assertNotDisposed } from "./Assert.js";
|
|
59
58
|
import { bytesToHex, hexToBytes } from "./Buffer.js";
|
|
60
59
|
import { createEqObject, eqArrayNumber, eqString } from "./Eq.js";
|
|
61
|
-
import {
|
|
60
|
+
import { disposable } from "./Function.js";
|
|
61
|
+
import { createMutableRecord, objectToEntries } from "./Object.js";
|
|
62
62
|
import { ok } from "./Result.js";
|
|
63
|
-
import { testCreateRun } from "./
|
|
63
|
+
import { testCreateRun } from "./Task.js";
|
|
64
64
|
import { array, Null, Number, object, record, set, String, testName, Uint8Array, union, } from "./Type.js";
|
|
65
65
|
/**
|
|
66
66
|
* A value that can be stored in {@link Sqlite}.
|
|
@@ -106,15 +106,10 @@ export const createSqlite = (name, options) => async (run) => {
|
|
|
106
106
|
const { createSqliteDriver } = run.deps;
|
|
107
107
|
const console = run.deps.console.child("sql");
|
|
108
108
|
const disposer = __addDisposableResource(env_1, new AsyncDisposableStack(), true);
|
|
109
|
-
const
|
|
110
|
-
if (!driverResult.ok)
|
|
111
|
-
return driverResult;
|
|
112
|
-
const driver = disposer.use(driverResult.value);
|
|
109
|
+
const driver = disposer.use(await run.ok(createSqliteDriver(name, options)));
|
|
113
110
|
console.debug("SQLite driver created");
|
|
114
|
-
|
|
115
|
-
const sqlite = {
|
|
111
|
+
return ok(disposable({
|
|
116
112
|
exec: (query) => {
|
|
117
|
-
assertNotDisposed(disposables);
|
|
118
113
|
console.debug({ query });
|
|
119
114
|
const label = query.options?.logQueryExecutionTime &&
|
|
120
115
|
`SqliteQueryExecutionTime ${query.sql}`;
|
|
@@ -137,7 +132,6 @@ export const createSqlite = (name, options) => async (run) => {
|
|
|
137
132
|
transaction: ((callback) => {
|
|
138
133
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
139
134
|
try {
|
|
140
|
-
assertNotDisposed(disposables);
|
|
141
135
|
console.debug("begin");
|
|
142
136
|
driver.exec(sql `begin;`);
|
|
143
137
|
const rollback = __addDisposableResource(env_2, new DisposableStack(), false);
|
|
@@ -164,13 +158,8 @@ export const createSqlite = (name, options) => async (run) => {
|
|
|
164
158
|
__disposeResources(env_2);
|
|
165
159
|
}
|
|
166
160
|
}),
|
|
167
|
-
export: () =>
|
|
168
|
-
|
|
169
|
-
return driver.export();
|
|
170
|
-
},
|
|
171
|
-
[Symbol.asyncDispose]: () => disposables.disposeAsync(),
|
|
172
|
-
};
|
|
173
|
-
return ok(sqlite);
|
|
161
|
+
export: () => driver.export(),
|
|
162
|
+
}, disposer));
|
|
174
163
|
}
|
|
175
164
|
catch (e_1) {
|
|
176
165
|
env_1.error = e_1;
|
|
@@ -188,10 +177,11 @@ export const testSetupSqlite = async (deps) => {
|
|
|
188
177
|
try {
|
|
189
178
|
const disposer = __addDisposableResource(env_3, new AsyncDisposableStack(), true);
|
|
190
179
|
const run = disposer.use(testCreateRun(deps));
|
|
191
|
-
const sqlite = disposer.use(await run.
|
|
180
|
+
const sqlite = disposer.use(await run.ok(createSqlite(testName, { mode: "memory" })));
|
|
181
|
+
const runWithSqlite = disposer.use(run.create({ ...run.deps, sqlite }));
|
|
192
182
|
const disposables = disposer.move();
|
|
193
183
|
return {
|
|
194
|
-
run:
|
|
184
|
+
run: runWithSqlite,
|
|
195
185
|
sqlite,
|
|
196
186
|
[Symbol.asyncDispose]: () => disposables.disposeAsync(),
|
|
197
187
|
};
|
|
@@ -249,10 +239,8 @@ export const createPreparedStatementsCache = (factory, disposeFn) => {
|
|
|
249
239
|
__disposeResources(env_5);
|
|
250
240
|
}
|
|
251
241
|
});
|
|
252
|
-
|
|
253
|
-
return {
|
|
242
|
+
return disposable({
|
|
254
243
|
get: (query, alwaysPrepare) => {
|
|
255
|
-
assertNotDisposed(disposables);
|
|
256
244
|
if (alwaysPrepare !== true && !query.options?.prepare)
|
|
257
245
|
return null;
|
|
258
246
|
let statement = statementsBySql.get(query.sql);
|
|
@@ -262,8 +250,7 @@ export const createPreparedStatementsCache = (factory, disposeFn) => {
|
|
|
262
250
|
}
|
|
263
251
|
return statement;
|
|
264
252
|
},
|
|
265
|
-
|
|
266
|
-
};
|
|
253
|
+
}, disposer);
|
|
267
254
|
}
|
|
268
255
|
catch (e_4) {
|
|
269
256
|
env_4.error = e_4;
|
|
@@ -282,27 +269,32 @@ export const createPreparedStatementsCache = (factory, disposeFn) => {
|
|
|
282
269
|
* ### Example
|
|
283
270
|
*
|
|
284
271
|
* ```ts
|
|
272
|
+
* import { sql } from "@evolu/common";
|
|
273
|
+
*
|
|
285
274
|
* const id = 42;
|
|
286
275
|
* const name = "Alice";
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
* from users
|
|
291
|
-
* where id = ${id} and name = ${name};
|
|
292
|
-
* `);
|
|
293
|
-
*
|
|
294
|
-
* // For identifiers
|
|
276
|
+
* const select = sql`
|
|
277
|
+
* select * from users where id = ${id} and name = ${name};
|
|
278
|
+
* `;
|
|
295
279
|
* const tableName = "users";
|
|
296
|
-
*
|
|
280
|
+
* const createTable = sql`
|
|
297
281
|
* create table ${sql.identifier(tableName)} (
|
|
298
282
|
* "id" text primary key,
|
|
299
283
|
* "name" text not null
|
|
300
284
|
* );
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
* // For raw SQL (use with caution)
|
|
285
|
+
* `;
|
|
286
|
+
* // Use sql.raw only with trusted SQL fragments.
|
|
304
287
|
* const orderBy = "created_at desc";
|
|
305
|
-
*
|
|
288
|
+
* const ordered = sql`select * from users order by ${sql.raw(orderBy)};`;
|
|
289
|
+
*
|
|
290
|
+
* expect(select).toEqual({
|
|
291
|
+
* sql: "select * from users where id = ? and name = ?;",
|
|
292
|
+
* parameters: [42, "Alice"],
|
|
293
|
+
* });
|
|
294
|
+
* expect(createTable.sql).toContain('create table "users"');
|
|
295
|
+
* expect(ordered.sql).toBe(
|
|
296
|
+
* "select * from users order by created_at desc;",
|
|
297
|
+
* );
|
|
306
298
|
* ```
|
|
307
299
|
*
|
|
308
300
|
* ## TIP
|
|
@@ -364,7 +356,7 @@ export const SqliteSchema = /*#__PURE__*/ object({
|
|
|
364
356
|
});
|
|
365
357
|
/** Get the current SQLite schema by reading SQLite metadata. */
|
|
366
358
|
export const getSqliteSchema = (deps) => ({ excludeIndexNamePrefix, } = {}) => {
|
|
367
|
-
const tables =
|
|
359
|
+
const tables = createMutableRecord();
|
|
368
360
|
const tableAndColumnInfoRows = deps.sqlite.exec(sql `
|
|
369
361
|
select
|
|
370
362
|
sqlite_master.name as tableName,
|
|
@@ -379,6 +371,7 @@ export const getSqliteSchema = (deps) => ({ excludeIndexNamePrefix, } = {}) => {
|
|
|
379
371
|
const indexNamePrefixFilter = excludeIndexNamePrefix != null
|
|
380
372
|
? ` and name not like '${excludeIndexNamePrefix.replaceAll("'", "''")}%'`
|
|
381
373
|
: "";
|
|
374
|
+
// prettier-ignore
|
|
382
375
|
const indexesRows = deps.sqlite.exec(sql `
|
|
383
376
|
select name, sql
|
|
384
377
|
from sqlite_master
|
|
@@ -390,9 +383,9 @@ export const getSqliteSchema = (deps) => ({ excludeIndexNamePrefix, } = {}) => {
|
|
|
390
383
|
const indexes = indexesRows.rows.map((row) => ({
|
|
391
384
|
name: row.name,
|
|
392
385
|
/**
|
|
393
|
-
* SQLite returns "CREATE INDEX" for "create index" for some reason.
|
|
394
|
-
*
|
|
395
|
-
*
|
|
386
|
+
* SQLite returns "CREATE INDEX" for "create index" for some reason. Other
|
|
387
|
+
* keywords remain unchanged. We have to normalize the casing for schema
|
|
388
|
+
* comparison manually.
|
|
396
389
|
*/
|
|
397
390
|
sql: row.sql
|
|
398
391
|
.replace("CREATE INDEX", "create index")
|
|
@@ -452,8 +445,9 @@ export const sqliteFalse = 0;
|
|
|
452
445
|
* ### Example
|
|
453
446
|
*
|
|
454
447
|
* ```ts
|
|
455
|
-
*
|
|
456
|
-
*
|
|
448
|
+
* import { booleanToSqliteBoolean } from "@evolu/common";
|
|
449
|
+
*
|
|
450
|
+
* expect(booleanToSqliteBoolean(true)).toBe(1);
|
|
457
451
|
* ```
|
|
458
452
|
*/
|
|
459
453
|
export const booleanToSqliteBoolean = (value) => value ? sqliteTrue : sqliteFalse;
|
|
@@ -463,8 +457,9 @@ export const booleanToSqliteBoolean = (value) => value ? sqliteTrue : sqliteFals
|
|
|
463
457
|
* ### Example
|
|
464
458
|
*
|
|
465
459
|
* ```ts
|
|
466
|
-
*
|
|
467
|
-
*
|
|
460
|
+
* import { sqliteBooleanToBoolean } from "@evolu/common";
|
|
461
|
+
*
|
|
462
|
+
* expect(sqliteBooleanToBoolean(1)).toBe(true);
|
|
468
463
|
* ```
|
|
469
464
|
*/
|
|
470
465
|
export const sqliteBooleanToBoolean = (value) => value === sqliteTrue;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript stack trace parsing utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
export interface StackTraceFrame {
|
|
7
|
+
/** Function or frame label reported by the engine, if available. */
|
|
8
|
+
readonly name: string | undefined;
|
|
9
|
+
/** Basename of the source location without query or hash suffixes. */
|
|
10
|
+
readonly sourceName: string;
|
|
11
|
+
readonly location: string;
|
|
12
|
+
readonly lineNumber: number;
|
|
13
|
+
readonly columnNumber: number;
|
|
14
|
+
}
|
|
15
|
+
export interface StackTrace {
|
|
16
|
+
readonly frames: ReadonlyArray<StackTraceFrame>;
|
|
17
|
+
readonly names: ReadonlyArray<string>;
|
|
18
|
+
readonly files: ReadonlyArray<string>;
|
|
19
|
+
readonly sites: ReadonlyArray<string>;
|
|
20
|
+
}
|
|
21
|
+
export interface StackTraceOptions {
|
|
22
|
+
readonly maxSourceLabelLineOffset?: number;
|
|
23
|
+
readonly sourceLabel?: string;
|
|
24
|
+
readonly sourceLabelsByLine?: Map<number, string>;
|
|
25
|
+
readonly sourceNameAllowlist?: ReadonlySet<string>;
|
|
26
|
+
readonly sourceName?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parses V8, SpiderMonkey, and JavaScriptCore stack frames for tests.
|
|
30
|
+
*
|
|
31
|
+
* Warning: This is AI-slop containment code for tests, not production stack
|
|
32
|
+
* trace parsing infrastructure.
|
|
33
|
+
*
|
|
34
|
+
* This is intentionally not a complete stack trace parser. It extracts only
|
|
35
|
+
* frame names and source positions needed by async stack trace tests and
|
|
36
|
+
* similar assertions that need stable, cross-engine stack evidence.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseStackTrace(stack: string | undefined, options?: StackTraceOptions): StackTrace;
|
|
39
|
+
export declare function parseStackTrace(run: () => Promise<never>, options?: StackTraceOptions): Promise<StackTrace>;
|
|
40
|
+
//# sourceMappingURL=StackTrace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StackTrace.d.ts","sourceRoot":"","sources":["../../src/StackTrace.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,UAAU,CAAC;AACd,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EACzB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript stack trace parsing utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
export function parseStackTrace(input, options = {}) {
|
|
7
|
+
if (typeof input === "function")
|
|
8
|
+
return (async () => {
|
|
9
|
+
try {
|
|
10
|
+
if (options.sourceLabel != null)
|
|
11
|
+
parseStackTrace(new Error().stack, options);
|
|
12
|
+
await input();
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (!(error instanceof Error))
|
|
16
|
+
throw error;
|
|
17
|
+
const { sourceLabel: _sourceLabel, ...readOptions } = options;
|
|
18
|
+
return parseStackTrace(error.stack, readOptions);
|
|
19
|
+
}
|
|
20
|
+
throw new Error("Stack trace capture must throw.");
|
|
21
|
+
})();
|
|
22
|
+
const frames = parseStackTraceFrames(input).filter(({ sourceName }) => options.sourceNameAllowlist == null ||
|
|
23
|
+
options.sourceNameAllowlist.has(sourceName));
|
|
24
|
+
recordSourceLabel(frames, options);
|
|
25
|
+
return {
|
|
26
|
+
files: frames.map(({ sourceName }) => sourceName),
|
|
27
|
+
frames,
|
|
28
|
+
names: frames
|
|
29
|
+
.map(({ name }) => name)
|
|
30
|
+
.filter((name) => name !== undefined),
|
|
31
|
+
sites: sourceLabels(frames, options),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const parseStackTraceFrames = (stack) => (stack ?? "")
|
|
35
|
+
.split("\n")
|
|
36
|
+
.map(parseStackTraceLine)
|
|
37
|
+
.filter((frame) => frame !== undefined);
|
|
38
|
+
const recordSourceLabel = (frames, { sourceLabel, sourceLabelsByLine, sourceName }) => {
|
|
39
|
+
if (sourceLabel == null || sourceLabelsByLine == null || sourceName == null)
|
|
40
|
+
return;
|
|
41
|
+
const frame = frames.find((frame) => frame.sourceName === sourceName);
|
|
42
|
+
if (frame == null)
|
|
43
|
+
return;
|
|
44
|
+
sourceLabelsByLine.set(frame.lineNumber, sourceLabel);
|
|
45
|
+
};
|
|
46
|
+
const sourceLabels = (frames, { maxSourceLabelLineOffset = 8, sourceLabelsByLine, sourceName, }) => {
|
|
47
|
+
if (sourceLabelsByLine == null || sourceName == null)
|
|
48
|
+
return [];
|
|
49
|
+
return frames.flatMap((frame) => {
|
|
50
|
+
if (frame.sourceName !== sourceName)
|
|
51
|
+
return [];
|
|
52
|
+
for (let offset = 0; offset <= maxSourceLabelLineOffset; offset += 1) {
|
|
53
|
+
const label = sourceLabelsByLine.get(frame.lineNumber - offset);
|
|
54
|
+
if (label != null)
|
|
55
|
+
return [label];
|
|
56
|
+
}
|
|
57
|
+
return [];
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
const parseStackTraceLine = (line) => {
|
|
61
|
+
const stackLine = parseStackLine(line);
|
|
62
|
+
if (stackLine == null)
|
|
63
|
+
return undefined;
|
|
64
|
+
const location = parseStackLocation(stackLine.location);
|
|
65
|
+
if (location == null)
|
|
66
|
+
return undefined;
|
|
67
|
+
return { ...location, name: stackLine.name };
|
|
68
|
+
};
|
|
69
|
+
const parseStackLine = (line) => {
|
|
70
|
+
let text = line.trim();
|
|
71
|
+
if (text === "")
|
|
72
|
+
return undefined;
|
|
73
|
+
if (text.startsWith("at ")) {
|
|
74
|
+
text = text.slice(3);
|
|
75
|
+
if (text.startsWith("async "))
|
|
76
|
+
text = text.slice(6);
|
|
77
|
+
const locationStart = text.lastIndexOf("(");
|
|
78
|
+
if (locationStart >= 0 && text.endsWith(")")) {
|
|
79
|
+
const name = stackFrameName(text.slice(0, locationStart).trim());
|
|
80
|
+
const location = text.slice(locationStart + 1, -1);
|
|
81
|
+
return { name, location };
|
|
82
|
+
}
|
|
83
|
+
return { location: text, name: undefined };
|
|
84
|
+
}
|
|
85
|
+
if (text.startsWith("async*"))
|
|
86
|
+
text = text.slice(6);
|
|
87
|
+
const locationStart = text.indexOf("@");
|
|
88
|
+
if (locationStart < 0)
|
|
89
|
+
return { location: text, name: undefined };
|
|
90
|
+
return {
|
|
91
|
+
location: text.slice(locationStart + 1),
|
|
92
|
+
name: stackFrameName(text.slice(0, locationStart)),
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const parseStackLocation = (location) => {
|
|
96
|
+
const columnStart = location.lastIndexOf(":");
|
|
97
|
+
if (columnStart < 0)
|
|
98
|
+
return undefined;
|
|
99
|
+
const lineStart = location.lastIndexOf(":", columnStart - 1);
|
|
100
|
+
if (lineStart < 0)
|
|
101
|
+
return undefined;
|
|
102
|
+
const pathEnd = Math.max(location.lastIndexOf("/"), location.lastIndexOf("\\"));
|
|
103
|
+
if (lineStart <= pathEnd)
|
|
104
|
+
return undefined;
|
|
105
|
+
const lineNumber = parseLeadingInt(location.slice(lineStart + 1));
|
|
106
|
+
const columnNumber = parseLeadingInt(location.slice(columnStart + 1));
|
|
107
|
+
if (lineNumber == null || columnNumber == null)
|
|
108
|
+
return undefined;
|
|
109
|
+
return {
|
|
110
|
+
columnNumber,
|
|
111
|
+
lineNumber,
|
|
112
|
+
location,
|
|
113
|
+
sourceName: stackTraceSourceName(location.slice(0, lineStart)),
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
const stackTraceSourceName = (source) => {
|
|
117
|
+
const queryStart = source.indexOf("?");
|
|
118
|
+
const hashStart = source.indexOf("#");
|
|
119
|
+
const suffixStart = queryStart < 0
|
|
120
|
+
? hashStart
|
|
121
|
+
: hashStart < 0
|
|
122
|
+
? queryStart
|
|
123
|
+
: Math.min(queryStart, hashStart);
|
|
124
|
+
const path = suffixStart < 0 ? source : source.slice(0, suffixStart);
|
|
125
|
+
return path.slice(Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1);
|
|
126
|
+
};
|
|
127
|
+
const parseLeadingInt = (value) => {
|
|
128
|
+
let end = 0;
|
|
129
|
+
while (end < value.length && isAsciiDigit(value.charCodeAt(end)))
|
|
130
|
+
end += 1;
|
|
131
|
+
if (end === 0)
|
|
132
|
+
return undefined;
|
|
133
|
+
return Number(value.slice(0, end));
|
|
134
|
+
};
|
|
135
|
+
const isAsciiDigit = (charCode) => charCode >= 48 && charCode <= 57;
|
|
136
|
+
const stackFrameName = (value) => {
|
|
137
|
+
while (value.endsWith("/<"))
|
|
138
|
+
value = value.slice(0, -2);
|
|
139
|
+
return value === "" ? undefined : value;
|
|
140
|
+
};
|
package/dist/src/Store.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type { Eq } from "./Eq.
|
|
7
|
-
import type { Ref } from "./Ref.
|
|
6
|
+
import type { Eq } from "./Eq.ts";
|
|
7
|
+
import type { Ref } from "./Ref.ts";
|
|
8
8
|
/**
|
|
9
9
|
* A store for managing state with change notifications. Like a {@link Ref} with
|
|
10
10
|
* subscriptions.
|
|
@@ -43,8 +43,9 @@ export type Unsubscribe = () => void;
|
|
|
43
43
|
* state, which can be read with `get` and updated with `set` or `update`. All
|
|
44
44
|
* changes are broadcast to subscribers.
|
|
45
45
|
*
|
|
46
|
-
* By default, state changes are detected using
|
|
47
|
-
*
|
|
46
|
+
* By default, state changes are detected using {@link eqSameValueZero}, which
|
|
47
|
+
* considers `NaN` equal to itself and `0` equal to `-0`. You can provide a
|
|
48
|
+
* custom equality function as the second argument.
|
|
48
49
|
*/
|
|
49
50
|
export declare const createStore: <T>(initialState: T, eq?: Eq<T>) => Store<T>;
|
|
50
51
|
//# sourceMappingURL=Store.d.ts.map
|
package/dist/src/Store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../src/Store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAGpC;;;;;;;GAOG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;CAAG;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,UAAU;IAClD,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,WAAW,CAAC;CACzD;AAED,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC
|
|
1
|
+
{"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../src/Store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAGpC;;;;;;;GAOG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;CAAG;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,UAAU;IAClD,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,WAAW,CAAC;CACzD;AAED,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,CAAC,CAqEnE,CAAC"}
|
package/dist/src/Store.js
CHANGED
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { eqSameValueZero } from "./Eq.js";
|
|
7
7
|
import { createRef } from "./Ref.js";
|
|
8
8
|
/**
|
|
9
9
|
* Creates a store with the given initial state. The store encapsulates its
|
|
10
10
|
* state, which can be read with `get` and updated with `set` or `update`. All
|
|
11
11
|
* changes are broadcast to subscribers.
|
|
12
12
|
*
|
|
13
|
-
* By default, state changes are detected using
|
|
14
|
-
*
|
|
13
|
+
* By default, state changes are detected using {@link eqSameValueZero}, which
|
|
14
|
+
* considers `NaN` equal to itself and `0` equal to `-0`. You can provide a
|
|
15
|
+
* custom equality function as the second argument.
|
|
15
16
|
*/
|
|
16
17
|
export const createStore = (initialState, eq) => {
|
|
17
|
-
const equality = eq ??
|
|
18
|
+
const equality = eq ?? eqSameValueZero;
|
|
18
19
|
const ref = createRef(initialState);
|
|
19
20
|
const listeners = new Set();
|
|
20
21
|
const notifyIfChanged = (previousState) => {
|
package/dist/src/String.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* String utilities
|
|
2
|
+
* String utilities.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Escapes regular-expression syntax so a string can be used as a literal
|
|
8
|
+
* pattern.
|
|
9
|
+
*/
|
|
10
|
+
export declare const escapeRegExp: (value: string) => string;
|
|
11
|
+
/** Converts an unknown value to a compact, human-readable diagnostic string. */
|
|
6
12
|
export declare const safelyStringifyUnknownValue: (value: unknown) => string;
|
|
7
13
|
//# sourceMappingURL=String.d.ts.map
|
package/dist/src/String.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"String.d.ts","sourceRoot":"","sources":["../../src/String.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,2BAA2B,
|
|
1
|
+
{"version":3,"file":"String.d.ts","sourceRoot":"","sources":["../../src/String.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,eAAO,MAAM,YAAY,UAAW,MAAM,KAAG,MACC,CAAC;AAE/C,gFAAgF;AAChF,eAAO,MAAM,2BAA2B,UAAW,OAAO,KAAG,MAkB5D,CAAC"}
|
package/dist/src/String.js
CHANGED
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* String utilities
|
|
2
|
+
* String utilities.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Escapes regular-expression syntax so a string can be used as a literal
|
|
8
|
+
* pattern.
|
|
9
|
+
*/
|
|
10
|
+
export const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11
|
+
/** Converts an unknown value to a compact, human-readable diagnostic string. */
|
|
6
12
|
export const safelyStringifyUnknownValue = (value) => {
|
|
7
|
-
if (value === null)
|
|
8
|
-
return "null";
|
|
9
|
-
if (value === undefined)
|
|
10
|
-
return "undefined";
|
|
11
13
|
if (typeof value === "string")
|
|
12
|
-
return `"${value}"`;
|
|
13
|
-
try {
|
|
14
14
|
return JSON.stringify(value);
|
|
15
|
+
if (value === null || typeof value !== "object")
|
|
16
|
+
return globalThis.String(value);
|
|
17
|
+
try {
|
|
18
|
+
// `JSON.stringify` can return `undefined` when `toJSON` does.
|
|
19
|
+
const stringifiedValue = JSON.stringify(value);
|
|
20
|
+
if (typeof stringifiedValue === "string")
|
|
21
|
+
return stringifiedValue;
|
|
15
22
|
}
|
|
16
23
|
catch {
|
|
24
|
+
// Fall through to a simpler representation.
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
17
27
|
return globalThis.String(value);
|
|
18
28
|
}
|
|
29
|
+
catch {
|
|
30
|
+
return "[Unserializable value]";
|
|
31
|
+
}
|
|
19
32
|
};
|