@proteinjs/db 1.25.2 → 1.27.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/CHANGELOG.md +17 -0
- package/LICENSE +21 -0
- package/dist/generated/index.js +7 -7
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.js +5 -5
- package/dist/generated/test/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/src/Db.d.ts +66 -6
- package/dist/src/Db.d.ts.map +1 -1
- package/dist/src/Db.js +242 -30
- package/dist/src/Db.js.map +1 -1
- package/dist/src/MigrationRunner.d.ts.map +1 -1
- package/dist/src/MigrationRunner.js +6 -0
- package/dist/src/MigrationRunner.js.map +1 -1
- package/dist/src/UpdatePreserving.d.ts +34 -0
- package/dist/src/UpdatePreserving.d.ts.map +1 -0
- package/dist/src/UpdatePreserving.js +72 -0
- package/dist/src/UpdatePreserving.js.map +1 -0
- package/dist/src/auth/TableAuth.d.ts +9 -0
- package/dist/src/auth/TableAuth.d.ts.map +1 -1
- package/dist/src/auth/TableAuth.js +36 -5
- package/dist/src/auth/TableAuth.js.map +1 -1
- package/dist/src/auth/TableServiceAuth.d.ts +7 -0
- package/dist/src/auth/TableServiceAuth.d.ts.map +1 -1
- package/dist/src/auth/TableServiceAuth.js +34 -0
- package/dist/src/auth/TableServiceAuth.js.map +1 -1
- package/dist/src/reference/ArrayMembershipOps.d.ts +69 -0
- package/dist/src/reference/ArrayMembershipOps.d.ts.map +1 -0
- package/dist/src/reference/ArrayMembershipOps.js +146 -0
- package/dist/src/reference/ArrayMembershipOps.js.map +1 -0
- package/dist/src/services/DbService.d.ts +38 -0
- package/dist/src/services/DbService.d.ts.map +1 -1
- package/dist/src/services/DbService.js.map +1 -1
- package/dist/src/transaction/Transaction.d.ts +19 -2
- package/dist/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/src/transaction/Transaction.js +38 -0
- package/dist/src/transaction/Transaction.js.map +1 -1
- package/dist/src/transaction/TransactionContextFactory.d.ts +18 -1
- package/dist/src/transaction/TransactionContextFactory.d.ts.map +1 -1
- package/dist/test/ArrayMembershipOps.test.d.ts +2 -0
- package/dist/test/ArrayMembershipOps.test.d.ts.map +1 -0
- package/dist/test/ArrayMembershipOps.test.js +147 -0
- package/dist/test/ArrayMembershipOps.test.js.map +1 -0
- package/dist/test/TableServiceAuth.test.js +108 -4
- package/dist/test/TableServiceAuth.test.js.map +1 -1
- package/generated/index.ts +18 -21
- package/generated/test/index.ts +41 -44
- package/index.ts +2 -0
- package/package.json +6 -5
- package/src/Db.ts +202 -24
- package/src/MigrationRunner.ts +6 -0
- package/src/UpdatePreserving.ts +89 -0
- package/src/auth/TableAuth.ts +17 -4
- package/src/auth/TableServiceAuth.ts +36 -1
- package/src/reference/ArrayMembershipOps.ts +155 -0
- package/src/services/DbService.ts +38 -0
- package/src/transaction/Transaction.ts +52 -2
- package/src/transaction/TransactionContextFactory.ts +19 -1
- package/test/ArrayMembershipOps.test.ts +160 -0
- package/test/TableServiceAuth.test.ts +148 -4
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Commutative membership operations for `ReferenceArrayColumn` values.
|
|
4
|
+
*
|
|
5
|
+
* Motivation (the write-side lost-update class): a client writer that persists a
|
|
6
|
+
* reference-array column as a FULL ID LIST snapshots its in-memory state — when two
|
|
7
|
+
* such writes race (fire-and-forget issuance + driver-level abort/retry can commit
|
|
8
|
+
* an earlier-issued transaction later), the last commit wins wholesale and erases
|
|
9
|
+
* the other writer's committed membership change. Expressing membership changes as
|
|
10
|
+
* ops (add/remove/move) applied read-modify-write against COMMITTED truth inside a
|
|
11
|
+
* transaction makes concurrent writes converge instead of clobber:
|
|
12
|
+
* `remove(x)` + `remove(y)` in any commit order removes both; `add(x)` + `add(y)`
|
|
13
|
+
* keeps both.
|
|
14
|
+
*
|
|
15
|
+
* `applyArrayMembershipOps` is the single applier used by `Db.updateArrayMembership`
|
|
16
|
+
* (server-side RMW) — and by any test that needs the committed rule as importable
|
|
17
|
+
* truth. `computeArrayMembershipOps` derives the minimal op set from a
|
|
18
|
+
* before/after id-list pair, for callers whose op layer only knows list states.
|
|
19
|
+
*/
|
|
20
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
21
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
22
|
+
if (ar || !(i in from)) {
|
|
23
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
24
|
+
ar[i] = from[i];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.computeArrayMembershipOps = exports.applyArrayMembershipOps = void 0;
|
|
31
|
+
/**
|
|
32
|
+
* Apply membership ops to an id list. Pure; returns a new array and whether it
|
|
33
|
+
* differs from the input.
|
|
34
|
+
*
|
|
35
|
+
* Anchor resolution (`afterId`) against a diverged committed list is
|
|
36
|
+
* convergence-by-anchor: a missing anchor appends at the end (the anchor was
|
|
37
|
+
* concurrently removed — the element still lands in the list, order is
|
|
38
|
+
* best-effort), `afterId: null` inserts at the head.
|
|
39
|
+
*/
|
|
40
|
+
function applyArrayMembershipOps(currentIds, ops) {
|
|
41
|
+
var ids = __spreadArray([], currentIds, true);
|
|
42
|
+
for (var _i = 0, ops_1 = ops; _i < ops_1.length; _i++) {
|
|
43
|
+
var op = ops_1[_i];
|
|
44
|
+
if (op.op === 'remove') {
|
|
45
|
+
var idx = ids.indexOf(op.id);
|
|
46
|
+
if (idx !== -1) {
|
|
47
|
+
ids.splice(idx, 1);
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (op.op === 'move' && ids.indexOf(op.id) === -1) {
|
|
52
|
+
// Move of a concurrently-removed element: the remove intent wins.
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// add (insert or reposition) and move (reposition) share placement logic.
|
|
56
|
+
var existingIdx = ids.indexOf(op.id);
|
|
57
|
+
if (existingIdx !== -1) {
|
|
58
|
+
ids.splice(existingIdx, 1);
|
|
59
|
+
}
|
|
60
|
+
if (op.afterId === null) {
|
|
61
|
+
ids.unshift(op.id);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
var anchorIdx = ids.indexOf(op.afterId);
|
|
65
|
+
if (anchorIdx === -1) {
|
|
66
|
+
ids.push(op.id);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
ids.splice(anchorIdx + 1, 0, op.id);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
var changed = ids.length !== currentIds.length || ids.some(function (id, i) { return id !== currentIds[i]; });
|
|
74
|
+
return { ids: ids, changed: changed };
|
|
75
|
+
}
|
|
76
|
+
exports.applyArrayMembershipOps = applyArrayMembershipOps;
|
|
77
|
+
/**
|
|
78
|
+
* Compute the op set that transforms `beforeIds` into `afterIds`.
|
|
79
|
+
*
|
|
80
|
+
* Removes first, then a single walk of `afterIds` emitting `add` for new
|
|
81
|
+
* elements and `move` for surviving elements whose relative order changed.
|
|
82
|
+
* Moves are minimized via the longest increasing subsequence of surviving
|
|
83
|
+
* elements (elements on the LIS stay put; everything else moves). Replaying
|
|
84
|
+
* the result on `beforeIds` yields exactly `afterIds`; replaying it on a
|
|
85
|
+
* DIVERGED committed list converges by anchor instead of clobbering.
|
|
86
|
+
*/
|
|
87
|
+
function computeArrayMembershipOps(beforeIds, afterIds) {
|
|
88
|
+
var before = beforeIds;
|
|
89
|
+
var after = afterIds;
|
|
90
|
+
var beforeSet = new Set(before);
|
|
91
|
+
var afterSet = new Set(after);
|
|
92
|
+
var ops = [];
|
|
93
|
+
for (var _i = 0, before_1 = before; _i < before_1.length; _i++) {
|
|
94
|
+
var id = before_1[_i];
|
|
95
|
+
if (!afterSet.has(id)) {
|
|
96
|
+
ops.push({ op: 'remove', id: id });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Surviving elements, in after-order, with their positions in `before`.
|
|
100
|
+
var surviving = after.filter(function (id) { return beforeSet.has(id); });
|
|
101
|
+
var beforeIndex = new Map(before.map(function (id, i) { return [id, i]; }));
|
|
102
|
+
var stable = longestIncreasingSubsequence(surviving.map(function (id) { return beforeIndex.get(id); }));
|
|
103
|
+
var stableIds = new Set(stable.map(function (i) { return surviving[i]; }));
|
|
104
|
+
for (var i = 0; i < after.length; i++) {
|
|
105
|
+
var id = after[i];
|
|
106
|
+
var afterId = i === 0 ? null : after[i - 1];
|
|
107
|
+
if (!beforeSet.has(id)) {
|
|
108
|
+
ops.push({ op: 'add', id: id, afterId: afterId });
|
|
109
|
+
}
|
|
110
|
+
else if (!stableIds.has(id)) {
|
|
111
|
+
ops.push({ op: 'move', id: id, afterId: afterId });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return ops;
|
|
115
|
+
}
|
|
116
|
+
exports.computeArrayMembershipOps = computeArrayMembershipOps;
|
|
117
|
+
/** Indices (into the input array) of one longest strictly-increasing subsequence. */
|
|
118
|
+
function longestIncreasingSubsequence(values) {
|
|
119
|
+
var tailIndices = [];
|
|
120
|
+
var prev = new Array(values.length).fill(-1);
|
|
121
|
+
for (var i = 0; i < values.length; i++) {
|
|
122
|
+
var lo = 0;
|
|
123
|
+
var hi = tailIndices.length;
|
|
124
|
+
while (lo < hi) {
|
|
125
|
+
var mid = (lo + hi) >> 1;
|
|
126
|
+
if (values[tailIndices[mid]] < values[i]) {
|
|
127
|
+
lo = mid + 1;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
hi = mid;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (lo > 0) {
|
|
134
|
+
prev[i] = tailIndices[lo - 1];
|
|
135
|
+
}
|
|
136
|
+
tailIndices[lo] = i;
|
|
137
|
+
}
|
|
138
|
+
var result = [];
|
|
139
|
+
var k = tailIndices.length > 0 ? tailIndices[tailIndices.length - 1] : -1;
|
|
140
|
+
while (k !== -1) {
|
|
141
|
+
result.unshift(k);
|
|
142
|
+
k = prev[k];
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=ArrayMembershipOps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArrayMembershipOps.js","sourceRoot":"","sources":["../../../src/reference/ArrayMembershipOps.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,8 @@ import { Service } from '@proteinjs/service';
|
|
|
2
2
|
import { Table } from '../Table';
|
|
3
3
|
import { Record } from '../Record';
|
|
4
4
|
import { QueryBuilder } from '@proteinjs/db-query';
|
|
5
|
+
import { ArrayMembershipUpdate } from '../reference/ArrayMembershipOps';
|
|
6
|
+
import { PreservedPath } from '../UpdatePreserving';
|
|
5
7
|
export declare const getDbService: () => DbService<Record>;
|
|
6
8
|
export type Query<T> = ObjectQuery<T> | QueryBuilder<T>;
|
|
7
9
|
export type ObjectQuery<T> = Partial<{
|
|
@@ -25,6 +27,42 @@ export interface DbService<R extends Record = Record> extends Service {
|
|
|
25
27
|
get<T extends R>(table: Table<T>, query: Query<T>, options?: QueryOptions<T>): Promise<T>;
|
|
26
28
|
insert<T extends R>(table: Table<T>, record: Omit<T, keyof R>): Promise<T>;
|
|
27
29
|
update<T extends R>(table: Table<T>, record: Partial<T>, query?: Query<T>): Promise<number>;
|
|
30
|
+
/**
|
|
31
|
+
* Apply commutative membership ops (add/remove/move) to a `ReferenceArrayColumn`,
|
|
32
|
+
* read-modify-write against COMMITTED truth inside a server-side transaction, so concurrent
|
|
33
|
+
* membership writers converge instead of last-write-wins clobbering each other (the
|
|
34
|
+
* write-side lost-update class).
|
|
35
|
+
*
|
|
36
|
+
* Use when the column has a NAMED multi-writer split — more than one writer changes the
|
|
37
|
+
* list's membership concurrently. Use plain `update` when the column has a single writer,
|
|
38
|
+
* or when the intent genuinely is wholesale assignment of the entire list.
|
|
39
|
+
*
|
|
40
|
+
* Authorization is identical to `update`: the table's `update` grant gates the call, and
|
|
41
|
+
* scoped/column query injection applies to the server-side read-modify-write — a scoped
|
|
42
|
+
* caller can only touch rows they could already update (an out-of-scope record behaves as
|
|
43
|
+
* nonexistent: returns 0).
|
|
44
|
+
*
|
|
45
|
+
* @returns the update count (0 when the ops are a no-op against committed truth, or the
|
|
46
|
+
* record does not exist / is not visible to the caller)
|
|
47
|
+
*/
|
|
48
|
+
updateArrayMembership<T extends R>(table: Table<T>, update: ArrayMembershipUpdate): Promise<number>;
|
|
49
|
+
/**
|
|
50
|
+
* Update with committed-truth preservation for column sub-paths the writer does not own:
|
|
51
|
+
* the payload's listed paths are overlaid with their committed values (read in the same
|
|
52
|
+
* server-side transaction), so this write commutes with the writers that own those paths.
|
|
53
|
+
* Plain-JSON columns only.
|
|
54
|
+
*
|
|
55
|
+
* Use when ownership of a column's VALUE is split across writers by sub-path (e.g. a
|
|
56
|
+
* structural editor op writes an object's styling while a debounced text save owns
|
|
57
|
+
* `content` — the structural payload's `content` is stale by construction). Use plain
|
|
58
|
+
* `update` when the writer owns the whole value it writes.
|
|
59
|
+
*
|
|
60
|
+
* Authorization is identical to `update` (update grant, scoped/column query injection,
|
|
61
|
+
* `serviceProtectedColumns` enforced on the payload).
|
|
62
|
+
*
|
|
63
|
+
* @returns the update count (0 when the record does not exist / is not visible to the caller)
|
|
64
|
+
*/
|
|
65
|
+
updatePreserving<T extends R>(table: Table<T>, record: Partial<T>, preserve: PreservedPath[]): Promise<number>;
|
|
28
66
|
delete<T extends R>(table: Table<T>, query: Query<T>): Promise<number>;
|
|
29
67
|
query<T extends R>(table: Table<T>, query: Query<T>, options?: QueryOptions<T>): Promise<T[]>;
|
|
30
68
|
getRowCount<T extends R>(table: Table<T>, query?: Query<T>): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DbService.d.ts","sourceRoot":"","sources":["../../../src/services/DbService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"DbService.d.ts","sourceRoot":"","sources":["../../../src/services/DbService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DbService.js","sourceRoot":"","sources":["../../../src/services/DbService.ts"],"names":[],"mappings":";;;AAAA,8CAA6D;
|
|
1
|
+
{"version":3,"file":"DbService.js","sourceRoot":"","sources":["../../../src/services/DbService.ts"],"names":[],"mappings":";;;AAAA,8CAA6D;AAOhD,QAAA,YAAY,GAAG,IAAA,wBAAc,EAAY,yBAAyB,CAAC,CAAC"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { Record } from '../Record';
|
|
2
2
|
import { DbService } from '../services/DbService';
|
|
3
3
|
import { Table } from '../Table';
|
|
4
|
+
import { ArrayMembershipUpdate } from '../reference/ArrayMembershipOps';
|
|
5
|
+
import { PreservedPath } from '../UpdatePreserving';
|
|
4
6
|
export type OperationQueue<R extends Record = Record> = {
|
|
5
7
|
insert: (...args: Parameters<DbService<R>['insert']>) => Promise<R>;
|
|
6
8
|
update: (...args: Parameters<DbService<R>['update']>) => void;
|
|
7
9
|
delete: (...args: Parameters<DbService<R>['delete']>) => void;
|
|
8
10
|
};
|
|
9
11
|
export type Operation<R extends Record = Record> = {
|
|
10
|
-
name: 'insert' | 'update' | 'delete';
|
|
11
|
-
args: Parameters<DbService<R>['insert']> | Parameters<DbService<R>['update']> | Parameters<DbService<R>['delete']
|
|
12
|
+
name: 'insert' | 'update' | 'delete' | 'updateArrayMembership' | 'updatePreserving';
|
|
13
|
+
args: Parameters<DbService<R>['insert']> | Parameters<DbService<R>['update']> | Parameters<DbService<R>['delete']> | [Table<any>, ArrayMembershipUpdate] | [Table<any>, Partial<R>, PreservedPath[]];
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* A queue of db write operations that are executed sequentially (not batched) as a single transaction when `run` is called.
|
|
@@ -61,6 +63,21 @@ export declare class Transaction implements OperationQueue {
|
|
|
61
63
|
* Passing in an `ObjectQuery` or a `QueryBuilder` with a `id IN string[]` condition will update the cached `db`.
|
|
62
64
|
*/
|
|
63
65
|
delete<R extends Record = Record>(...args: Parameters<DbService<R>['delete']>): void;
|
|
66
|
+
/**
|
|
67
|
+
* Queue a commutative array-membership update (see `Db.updateArrayMembership`).
|
|
68
|
+
*
|
|
69
|
+
* The op is applied read-modify-write against COMMITTED truth server-side, so it
|
|
70
|
+
* does not touch the local record cache (the caller's in-memory state is the
|
|
71
|
+
* client-side truth and was already mutated by the operation that queued this);
|
|
72
|
+
* `onUpdate` listeners do not fire for membership ops.
|
|
73
|
+
*/
|
|
74
|
+
updateArrayMembership(table: Table<any>, update: ArrayMembershipUpdate): void;
|
|
75
|
+
/**
|
|
76
|
+
* Queue an update with committed-truth preservation for the listed column
|
|
77
|
+
* sub-paths (see `Db.updatePreserving`). Cache semantics match `update`
|
|
78
|
+
* for the provided fields; the preservation itself happens server-side.
|
|
79
|
+
*/
|
|
80
|
+
updatePreserving<R extends Record = Record>(table: Table<R>, record: Partial<R>, preserve: PreservedPath[]): void;
|
|
64
81
|
/**
|
|
65
82
|
* If a QueryBuilder contains a condition like this:
|
|
66
83
|
* `{ field: 'id', operator: 'IN', value: string[] }`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.d.ts","sourceRoot":"","sources":["../../../src/transaction/Transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,SAAS,EAAe,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAyB,KAAK,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"Transaction.d.ts","sourceRoot":"","sources":["../../../src/transaction/Transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -240,6 +240,44 @@ var Transaction = /** @class */ (function () {
|
|
|
240
240
|
}
|
|
241
241
|
this.ops.push({ name: 'delete', args: args });
|
|
242
242
|
};
|
|
243
|
+
/**
|
|
244
|
+
* Queue a commutative array-membership update (see `Db.updateArrayMembership`).
|
|
245
|
+
*
|
|
246
|
+
* The op is applied read-modify-write against COMMITTED truth server-side, so it
|
|
247
|
+
* does not touch the local record cache (the caller's in-memory state is the
|
|
248
|
+
* client-side truth and was already mutated by the operation that queued this);
|
|
249
|
+
* `onUpdate` listeners do not fire for membership ops.
|
|
250
|
+
*/
|
|
251
|
+
Transaction.prototype.updateArrayMembership = function (table, update) {
|
|
252
|
+
if (update.ops.length === 0) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
this.ops.push({ name: 'updateArrayMembership', args: [table, update] });
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Queue an update with committed-truth preservation for the listed column
|
|
259
|
+
* sub-paths (see `Db.updatePreserving`). Cache semantics match `update`
|
|
260
|
+
* for the provided fields; the preservation itself happens server-side.
|
|
261
|
+
*/
|
|
262
|
+
Transaction.prototype.updatePreserving = function (table, record, preserve) {
|
|
263
|
+
if (!record.id) {
|
|
264
|
+
throw new Error("updatePreserving must be called with a record with an id property");
|
|
265
|
+
}
|
|
266
|
+
var recordMap = this.recordMap(table.name);
|
|
267
|
+
var existingRecord = recordMap[record.id];
|
|
268
|
+
if (existingRecord) {
|
|
269
|
+
var prevRecord = __assign({}, existingRecord);
|
|
270
|
+
Object.keys(record).forEach(function (key) {
|
|
271
|
+
if (key !== 'id') {
|
|
272
|
+
existingRecord[key] = record[key];
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
if (this.onUpdate) {
|
|
276
|
+
this.onUpdate(table, prevRecord, existingRecord);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
this.ops.push({ name: 'updatePreserving', args: [table, record, preserve] });
|
|
280
|
+
};
|
|
243
281
|
/**
|
|
244
282
|
* If a QueryBuilder contains a condition like this:
|
|
245
283
|
* `{ field: 'id', operator: 'IN', value: string[] }`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.js","sourceRoot":"","sources":["../../../src/transaction/Transaction.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yDAA2D;AAC3D,kCAAwD;AACxD,wCAA+C;AAC/C,gDAA8D;
|
|
1
|
+
{"version":3,"file":"Transaction.js","sourceRoot":"","sources":["../../../src/transaction/Transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { Loadable } from '@proteinjs/reflection';
|
|
2
2
|
export declare const getDefaultTransactionContextFactory: () => DefaultTransactionContextFactory;
|
|
3
|
+
/** See {@link TransactionContextData.postCommitHooks} and `Db.runAfterCommit`. */
|
|
4
|
+
export type PostCommitHook = () => void | Promise<void>;
|
|
3
5
|
export interface TransactionContextData {
|
|
4
6
|
currentTransaction?: any;
|
|
7
|
+
/**
|
|
8
|
+
* Hooks queued to run after the current transaction COMMITS — and never on rollback: a hook
|
|
9
|
+
* queued for a write that gets rolled back dies with the write. Seeded by `Db.runTransaction`
|
|
10
|
+
* on the ambient context so every `Db` instance created inside the transaction (table
|
|
11
|
+
* watchers, nested helpers) shares one queue; registered via `Db.runAfterCommit`, drained by
|
|
12
|
+
* `Db.runTransaction` once the driver reports the commit durable.
|
|
13
|
+
*/
|
|
14
|
+
postCommitHooks?: PostCommitHook[];
|
|
15
|
+
/**
|
|
16
|
+
* Set by `Db.runTransaction` when the transaction completes. Work spawned inside the
|
|
17
|
+
* transaction body but not awaited by it still holds this store by reference (the async
|
|
18
|
+
* context propagates) — the flag turns any later db operation from that escaped context
|
|
19
|
+
* into a loud, named error instead of silently handing the driver a finished transaction.
|
|
20
|
+
*/
|
|
21
|
+
ended?: boolean;
|
|
5
22
|
}
|
|
6
23
|
export interface DefaultTransactionContextFactory extends Loadable {
|
|
7
24
|
getTransactionContext(): TransactionContextData;
|
|
8
|
-
runInContext<T>(
|
|
25
|
+
runInContext<T>(context: TransactionContextData, fn: () => Promise<T>): Promise<T>;
|
|
9
26
|
}
|
|
10
27
|
//# sourceMappingURL=TransactionContextFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionContextFactory.d.ts","sourceRoot":"","sources":["../../../src/transaction/TransactionContextFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAEnE,eAAO,MAAM,mCAAmC,wCACmE,CAAC;AAEpH,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,CAAC,EAAE,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"TransactionContextFactory.d.ts","sourceRoot":"","sources":["../../../src/transaction/TransactionContextFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAEnE,eAAO,MAAM,mCAAmC,wCACmE,CAAC;AAEpH,kFAAkF;AAClF,MAAM,MAAM,cAAc,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAExD,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,CAAC,EAAE,GAAG,CAAC;IACzB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gCAAiC,SAAQ,QAAQ;IAChE,qBAAqB,IAAI,sBAAsB,CAAC;IAChD,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACpF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArrayMembershipOps.test.d.ts","sourceRoot":"","sources":["../../test/ArrayMembershipOps.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var ArrayMembershipOps_1 = require("../src/reference/ArrayMembershipOps");
|
|
4
|
+
var UpdatePreserving_1 = require("../src/UpdatePreserving");
|
|
5
|
+
var replay = function (before, after) {
|
|
6
|
+
return (0, ArrayMembershipOps_1.applyArrayMembershipOps)(before, (0, ArrayMembershipOps_1.computeArrayMembershipOps)(before, after)).ids;
|
|
7
|
+
};
|
|
8
|
+
describe('computeArrayMembershipOps + applyArrayMembershipOps', function () {
|
|
9
|
+
test('replaying the computed ops on the before-list yields exactly the after-list', function () {
|
|
10
|
+
var cases = [
|
|
11
|
+
[[], []],
|
|
12
|
+
[[], ['a']],
|
|
13
|
+
[['a'], []],
|
|
14
|
+
[
|
|
15
|
+
['a', 'b', 'c'],
|
|
16
|
+
['a', 'b', 'c'],
|
|
17
|
+
],
|
|
18
|
+
[
|
|
19
|
+
['a', 'b', 'c'],
|
|
20
|
+
['a', 'c'],
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
['a', 'c'],
|
|
24
|
+
['a', 'b', 'c'],
|
|
25
|
+
],
|
|
26
|
+
[
|
|
27
|
+
['a', 'b', 'c'],
|
|
28
|
+
['c', 'b', 'a'],
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
['a', 'b', 'c', 'd', 'e'],
|
|
32
|
+
['e', 'x', 'a', 'c'],
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
['a', 'b'],
|
|
36
|
+
['x', 'y', 'z'],
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
['a', 'b', 'c', 'd'],
|
|
40
|
+
['b', 'd', 'a', 'c'],
|
|
41
|
+
],
|
|
42
|
+
];
|
|
43
|
+
for (var _i = 0, cases_1 = cases; _i < cases_1.length; _i++) {
|
|
44
|
+
var _a = cases_1[_i], before = _a[0], after = _a[1];
|
|
45
|
+
expect(replay(before, after)).toEqual(after);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
test('no-op diff computes zero ops and apply reports unchanged', function () {
|
|
49
|
+
var ops = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(['a', 'b'], ['a', 'b']);
|
|
50
|
+
expect(ops).toEqual([]);
|
|
51
|
+
expect((0, ArrayMembershipOps_1.applyArrayMembershipOps)(['a', 'b'], ops).changed).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
test('unchanged relative order of survivors emits no move ops (pure adds/removes)', function () {
|
|
54
|
+
var ops = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(['a', 'b', 'c', 'd'], ['a', 'c', 'd', 'e']);
|
|
55
|
+
expect(ops).toEqual([
|
|
56
|
+
{ op: 'remove', id: 'b' },
|
|
57
|
+
{ op: 'add', id: 'e', afterId: 'd' },
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
test('CONVERGENCE: concurrent removes of different ids both land regardless of commit order', function () {
|
|
61
|
+
// Client A removes x, client B removes y; each computed against the same base.
|
|
62
|
+
var base = ['x', 'y', 'z'];
|
|
63
|
+
var opsA = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(base, ['y', 'z']);
|
|
64
|
+
var opsB = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(base, ['x', 'z']);
|
|
65
|
+
var abOrder = (0, ArrayMembershipOps_1.applyArrayMembershipOps)((0, ArrayMembershipOps_1.applyArrayMembershipOps)(base, opsA).ids, opsB).ids;
|
|
66
|
+
var baOrder = (0, ArrayMembershipOps_1.applyArrayMembershipOps)((0, ArrayMembershipOps_1.applyArrayMembershipOps)(base, opsB).ids, opsA).ids;
|
|
67
|
+
expect(abOrder).toEqual(['z']);
|
|
68
|
+
expect(baOrder).toEqual(['z']);
|
|
69
|
+
});
|
|
70
|
+
test('CONVERGENCE: concurrent adds of different ids both survive regardless of commit order', function () {
|
|
71
|
+
var base = ['a'];
|
|
72
|
+
var opsA = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(base, ['a', 'p']); // A appends p
|
|
73
|
+
var opsB = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(base, ['a', 'q']); // B appends q
|
|
74
|
+
var abOrder = (0, ArrayMembershipOps_1.applyArrayMembershipOps)((0, ArrayMembershipOps_1.applyArrayMembershipOps)(base, opsA).ids, opsB).ids;
|
|
75
|
+
var baOrder = (0, ArrayMembershipOps_1.applyArrayMembershipOps)((0, ArrayMembershipOps_1.applyArrayMembershipOps)(base, opsB).ids, opsA).ids;
|
|
76
|
+
expect(new Set(abOrder)).toEqual(new Set(['a', 'p', 'q']));
|
|
77
|
+
expect(new Set(baOrder)).toEqual(new Set(['a', 'p', 'q']));
|
|
78
|
+
});
|
|
79
|
+
test('CONVERGENCE: the founder burst — three sequential deletes converge under ANY commit order', function () {
|
|
80
|
+
// In-memory the client deletes d, then e, then f (each delta computed
|
|
81
|
+
// against its own pre-state, as deleteThought does). The wire commits in a
|
|
82
|
+
// reordered sequence (Spanner abort/retry): every permutation must end at
|
|
83
|
+
// the fully-deleted list — the pre-fix full-list snapshots resurrect rows.
|
|
84
|
+
var s0 = ['a', 'd', 'e', 'f'];
|
|
85
|
+
var del1 = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(s0, ['a', 'e', 'f']);
|
|
86
|
+
var del2 = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(['a', 'e', 'f'], ['a', 'f']);
|
|
87
|
+
var del3 = (0, ArrayMembershipOps_1.computeArrayMembershipOps)(['a', 'f'], ['a']);
|
|
88
|
+
var permutations = [
|
|
89
|
+
[del1, del2, del3],
|
|
90
|
+
[del1, del3, del2],
|
|
91
|
+
[del2, del1, del3],
|
|
92
|
+
[del2, del3, del1],
|
|
93
|
+
[del3, del1, del2],
|
|
94
|
+
[del3, del2, del1],
|
|
95
|
+
];
|
|
96
|
+
for (var _i = 0, permutations_1 = permutations; _i < permutations_1.length; _i++) {
|
|
97
|
+
var order = permutations_1[_i];
|
|
98
|
+
var ids = s0;
|
|
99
|
+
for (var _a = 0, order_1 = order; _a < order_1.length; _a++) {
|
|
100
|
+
var ops = order_1[_a];
|
|
101
|
+
ids = (0, ArrayMembershipOps_1.applyArrayMembershipOps)(ids, ops).ids;
|
|
102
|
+
}
|
|
103
|
+
expect(ids).toEqual(['a']);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
test('anchors: missing afterId appends at the end; null afterId inserts at the head; moves of removed ids are dropped', function () {
|
|
107
|
+
expect((0, ArrayMembershipOps_1.applyArrayMembershipOps)(['a', 'b'], [{ op: 'add', id: 'n', afterId: 'gone' }]).ids).toEqual(['a', 'b', 'n']);
|
|
108
|
+
expect((0, ArrayMembershipOps_1.applyArrayMembershipOps)(['a', 'b'], [{ op: 'add', id: 'n', afterId: null }]).ids).toEqual(['n', 'a', 'b']);
|
|
109
|
+
expect((0, ArrayMembershipOps_1.applyArrayMembershipOps)(['a', 'b'], [{ op: 'move', id: 'gone', afterId: 'a' }]).ids).toEqual(['a', 'b']);
|
|
110
|
+
expect((0, ArrayMembershipOps_1.applyArrayMembershipOps)(['a', 'b'], [{ op: 'add', id: 'b', afterId: null }]).ids).toEqual(['b', 'a']);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('overlayPreservedPaths', function () {
|
|
114
|
+
test('preserves the committed text content into a structural payload (the class-2 kill)', function () {
|
|
115
|
+
var committed = { content: 'Tab beta', type: 'body1' };
|
|
116
|
+
var incoming = { content: '', type: 'h6', fontSize: 12 };
|
|
117
|
+
expect((0, UpdatePreserving_1.overlayPreservedPaths)(committed, incoming, ['content'], 'string')).toEqual({
|
|
118
|
+
content: 'Tab beta',
|
|
119
|
+
type: 'h6',
|
|
120
|
+
fontSize: 12,
|
|
121
|
+
});
|
|
122
|
+
// The incoming payload object is not mutated.
|
|
123
|
+
expect(incoming.content).toBe('');
|
|
124
|
+
});
|
|
125
|
+
test('nested path (composite text object)', function () {
|
|
126
|
+
var committed = { content: { thoughtTypeId: 't', thoughtObject: { content: 'typed', type: 'body1' } } };
|
|
127
|
+
var incoming = { content: { thoughtTypeId: 't', thoughtObject: { content: '', type: 'h3' } } };
|
|
128
|
+
var out = (0, UpdatePreserving_1.overlayPreservedPaths)(committed, incoming, ['content.thoughtObject.content'], 'string');
|
|
129
|
+
expect(out.content.thoughtObject).toEqual({ content: 'typed', type: 'h3' });
|
|
130
|
+
});
|
|
131
|
+
test('whenType guards shape transitions: committed non-string content is not dragged into a new shape', function () {
|
|
132
|
+
var committedComposite = { content: { thoughtTypeId: 't', thoughtObject: { content: 'x' } } };
|
|
133
|
+
var incomingPlain = { content: 'fresh', type: 'body1' };
|
|
134
|
+
expect((0, UpdatePreserving_1.overlayPreservedPaths)(committedComposite, incomingPlain, ['content'], 'string')).toEqual(incomingPlain);
|
|
135
|
+
});
|
|
136
|
+
test('missing committed path keeps the incoming value (facet-init seeding survives)', function () {
|
|
137
|
+
var committed = { someOtherField: 1 };
|
|
138
|
+
var incoming = { content: 'seeded from description', type: 'body1' };
|
|
139
|
+
expect((0, UpdatePreserving_1.overlayPreservedPaths)(committed, incoming, ['content'], 'string')).toEqual(incoming);
|
|
140
|
+
});
|
|
141
|
+
test('incoming payload lacking the path parent is left untouched', function () {
|
|
142
|
+
var committed = { content: { thoughtTypeId: 't', thoughtObject: { content: 'x' } } };
|
|
143
|
+
var incoming = { plain: true };
|
|
144
|
+
expect((0, UpdatePreserving_1.overlayPreservedPaths)(committed, incoming, ['content.thoughtObject.content'], 'string')).toEqual(incoming);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=ArrayMembershipOps.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArrayMembershipOps.test.js","sourceRoot":"","sources":["../../test/ArrayMembershipOps.test.ts"],"names":[],"mappings":"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"}
|