@anuma/sdk 10.6.0 → 10.6.2
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/expo/index.cjs +50 -19
- package/dist/expo/index.mjs +50 -19
- package/dist/pii/transformers.cjs +22 -11
- package/dist/pii/transformers.d.mts +3 -6
- package/dist/pii/transformers.d.ts +3 -6
- package/dist/pii/transformers.mjs +22 -11
- package/dist/react/index.cjs +50 -19
- package/dist/react/index.mjs +50 -19
- package/dist/server/index.cjs +49 -19
- package/dist/server/index.mjs +49 -19
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -18537,6 +18537,52 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
18537
18537
|
trustTier: raw.trust_tier ?? null
|
|
18538
18538
|
}));
|
|
18539
18539
|
}
|
|
18540
|
+
async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
18541
|
+
assertVaultScopeForSweep(ctx);
|
|
18542
|
+
const byId = new Map(candidates.map((candidate) => [candidate.uniqueId, candidate]));
|
|
18543
|
+
const ids = Array.from(byId.keys());
|
|
18544
|
+
const changed = /* @__PURE__ */ new Set();
|
|
18545
|
+
const CHUNK = 500;
|
|
18546
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
18547
|
+
let applied = [];
|
|
18548
|
+
try {
|
|
18549
|
+
await ctx.database.write(async () => {
|
|
18550
|
+
await assertCanWrite2(ctx);
|
|
18551
|
+
const records = await ctx.vaultMemoryCollection.query(
|
|
18552
|
+
import_watermelondb21.Q.where("id", import_watermelondb21.Q.oneOf(ids.slice(i, i + CHUNK))),
|
|
18553
|
+
...ctx.userId !== void 0 ? [import_watermelondb21.Q.where("user_id", ctx.userId)] : []
|
|
18554
|
+
).fetch();
|
|
18555
|
+
const eligible = records.filter((record2) => {
|
|
18556
|
+
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
18557
|
+
if (opts.transition === "delete") {
|
|
18558
|
+
return record2.archivedAt !== null && opts.now - record2.archivedAt > opts.hardDeleteWindowMs;
|
|
18559
|
+
}
|
|
18560
|
+
const candidate = byId.get(record2.id);
|
|
18561
|
+
return record2.archivedAt === null && record2.updatedAt.getTime() === candidate.updatedAt && (record2.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
18562
|
+
});
|
|
18563
|
+
const prepared = eligible.map(
|
|
18564
|
+
(record2) => record2.prepareUpdate((row) => {
|
|
18565
|
+
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
18566
|
+
else row._setRaw("is_deleted", true);
|
|
18567
|
+
})
|
|
18568
|
+
);
|
|
18569
|
+
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
18570
|
+
applied = eligible.map((record2) => record2.id);
|
|
18571
|
+
});
|
|
18572
|
+
} catch {
|
|
18573
|
+
continue;
|
|
18574
|
+
}
|
|
18575
|
+
for (const id2 of applied) changed.add(id2);
|
|
18576
|
+
if (opts.transition === "delete" && ctx.entityCtx) {
|
|
18577
|
+
try {
|
|
18578
|
+
await unlinkMemoryEntitiesOp(ctx.entityCtx, applied);
|
|
18579
|
+
} catch {
|
|
18580
|
+
continue;
|
|
18581
|
+
}
|
|
18582
|
+
}
|
|
18583
|
+
}
|
|
18584
|
+
return changed;
|
|
18585
|
+
}
|
|
18540
18586
|
async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
18541
18587
|
try {
|
|
18542
18588
|
const record2 = await ctx.vaultMemoryCollection.find(id2);
|
|
@@ -23137,25 +23183,8 @@ function isBorderline(input) {
|
|
|
23137
23183
|
function vaultDecayBackend(vaultCtx) {
|
|
23138
23184
|
return {
|
|
23139
23185
|
candidates: () => getDecayCandidatesRawOp(vaultCtx),
|
|
23140
|
-
archive:
|
|
23141
|
-
|
|
23142
|
-
for (const c of rows) {
|
|
23143
|
-
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
23144
|
-
now,
|
|
23145
|
-
expectedUpdatedAt: c.updatedAt,
|
|
23146
|
-
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
23147
|
-
});
|
|
23148
|
-
if (ok) archived.add(c.uniqueId);
|
|
23149
|
-
}
|
|
23150
|
-
return archived;
|
|
23151
|
-
},
|
|
23152
|
-
hardDelete: async (rows, deleteOptions) => {
|
|
23153
|
-
const deleted = /* @__PURE__ */ new Set();
|
|
23154
|
-
for (const c of rows) {
|
|
23155
|
-
if (await hardDeleteDecayedOp(vaultCtx, c.uniqueId, deleteOptions)) deleted.add(c.uniqueId);
|
|
23156
|
-
}
|
|
23157
|
-
return deleted;
|
|
23158
|
-
}
|
|
23186
|
+
archive: (rows, now) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "archive", now }),
|
|
23187
|
+
hardDelete: (rows, deleteOptions) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "delete", ...deleteOptions })
|
|
23159
23188
|
};
|
|
23160
23189
|
}
|
|
23161
23190
|
function createDecaySweeper(options) {
|
|
@@ -25157,6 +25186,7 @@ function createLocalMemoryStore(options) {
|
|
|
25157
25186
|
"trust_tier",
|
|
25158
25187
|
"superseded_by",
|
|
25159
25188
|
"visibility",
|
|
25189
|
+
"twin_opt_in",
|
|
25160
25190
|
"published_at",
|
|
25161
25191
|
"geohash",
|
|
25162
25192
|
"topics",
|
|
@@ -26348,6 +26378,7 @@ function subscriptionState({ memory, version }) {
|
|
|
26348
26378
|
memory.event_time_kind,
|
|
26349
26379
|
memory.trust_tier,
|
|
26350
26380
|
memory.visibility,
|
|
26381
|
+
memory.twin_opt_in,
|
|
26351
26382
|
memory.published_at,
|
|
26352
26383
|
memory.geohash,
|
|
26353
26384
|
memory.topics,
|
package/dist/expo/index.mjs
CHANGED
|
@@ -16867,6 +16867,52 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
16867
16867
|
trustTier: raw.trust_tier ?? null
|
|
16868
16868
|
}));
|
|
16869
16869
|
}
|
|
16870
|
+
async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
16871
|
+
assertVaultScopeForSweep(ctx);
|
|
16872
|
+
const byId = new Map(candidates.map((candidate) => [candidate.uniqueId, candidate]));
|
|
16873
|
+
const ids = Array.from(byId.keys());
|
|
16874
|
+
const changed = /* @__PURE__ */ new Set();
|
|
16875
|
+
const CHUNK = 500;
|
|
16876
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
16877
|
+
let applied = [];
|
|
16878
|
+
try {
|
|
16879
|
+
await ctx.database.write(async () => {
|
|
16880
|
+
await assertCanWrite2(ctx);
|
|
16881
|
+
const records = await ctx.vaultMemoryCollection.query(
|
|
16882
|
+
Q6.where("id", Q6.oneOf(ids.slice(i, i + CHUNK))),
|
|
16883
|
+
...ctx.userId !== void 0 ? [Q6.where("user_id", ctx.userId)] : []
|
|
16884
|
+
).fetch();
|
|
16885
|
+
const eligible = records.filter((record2) => {
|
|
16886
|
+
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
16887
|
+
if (opts.transition === "delete") {
|
|
16888
|
+
return record2.archivedAt !== null && opts.now - record2.archivedAt > opts.hardDeleteWindowMs;
|
|
16889
|
+
}
|
|
16890
|
+
const candidate = byId.get(record2.id);
|
|
16891
|
+
return record2.archivedAt === null && record2.updatedAt.getTime() === candidate.updatedAt && (record2.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
16892
|
+
});
|
|
16893
|
+
const prepared = eligible.map(
|
|
16894
|
+
(record2) => record2.prepareUpdate((row) => {
|
|
16895
|
+
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
16896
|
+
else row._setRaw("is_deleted", true);
|
|
16897
|
+
})
|
|
16898
|
+
);
|
|
16899
|
+
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
16900
|
+
applied = eligible.map((record2) => record2.id);
|
|
16901
|
+
});
|
|
16902
|
+
} catch {
|
|
16903
|
+
continue;
|
|
16904
|
+
}
|
|
16905
|
+
for (const id2 of applied) changed.add(id2);
|
|
16906
|
+
if (opts.transition === "delete" && ctx.entityCtx) {
|
|
16907
|
+
try {
|
|
16908
|
+
await unlinkMemoryEntitiesOp(ctx.entityCtx, applied);
|
|
16909
|
+
} catch {
|
|
16910
|
+
continue;
|
|
16911
|
+
}
|
|
16912
|
+
}
|
|
16913
|
+
}
|
|
16914
|
+
return changed;
|
|
16915
|
+
}
|
|
16870
16916
|
async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
16871
16917
|
try {
|
|
16872
16918
|
const record2 = await ctx.vaultMemoryCollection.find(id2);
|
|
@@ -21436,25 +21482,8 @@ function isBorderline(input) {
|
|
|
21436
21482
|
function vaultDecayBackend(vaultCtx) {
|
|
21437
21483
|
return {
|
|
21438
21484
|
candidates: () => getDecayCandidatesRawOp(vaultCtx),
|
|
21439
|
-
archive:
|
|
21440
|
-
|
|
21441
|
-
for (const c of rows) {
|
|
21442
|
-
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
21443
|
-
now,
|
|
21444
|
-
expectedUpdatedAt: c.updatedAt,
|
|
21445
|
-
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
21446
|
-
});
|
|
21447
|
-
if (ok) archived.add(c.uniqueId);
|
|
21448
|
-
}
|
|
21449
|
-
return archived;
|
|
21450
|
-
},
|
|
21451
|
-
hardDelete: async (rows, deleteOptions) => {
|
|
21452
|
-
const deleted = /* @__PURE__ */ new Set();
|
|
21453
|
-
for (const c of rows) {
|
|
21454
|
-
if (await hardDeleteDecayedOp(vaultCtx, c.uniqueId, deleteOptions)) deleted.add(c.uniqueId);
|
|
21455
|
-
}
|
|
21456
|
-
return deleted;
|
|
21457
|
-
}
|
|
21485
|
+
archive: (rows, now) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "archive", now }),
|
|
21486
|
+
hardDelete: (rows, deleteOptions) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "delete", ...deleteOptions })
|
|
21458
21487
|
};
|
|
21459
21488
|
}
|
|
21460
21489
|
function createDecaySweeper(options) {
|
|
@@ -23441,6 +23470,7 @@ function createLocalMemoryStore(options) {
|
|
|
23441
23470
|
"trust_tier",
|
|
23442
23471
|
"superseded_by",
|
|
23443
23472
|
"visibility",
|
|
23473
|
+
"twin_opt_in",
|
|
23444
23474
|
"published_at",
|
|
23445
23475
|
"geohash",
|
|
23446
23476
|
"topics",
|
|
@@ -24627,6 +24657,7 @@ function subscriptionState({ memory, version }) {
|
|
|
24627
24657
|
memory.event_time_kind,
|
|
24628
24658
|
memory.trust_tier,
|
|
24629
24659
|
memory.visibility,
|
|
24660
|
+
memory.twin_opt_in,
|
|
24630
24661
|
memory.published_at,
|
|
24631
24662
|
memory.geohash,
|
|
24632
24663
|
memory.topics,
|
|
@@ -42,20 +42,24 @@ var DEFAULT_TAG_MAP = {
|
|
|
42
42
|
MISC: void 0
|
|
43
43
|
};
|
|
44
44
|
function placeTokens(tokens, text) {
|
|
45
|
-
|
|
45
|
+
return tokens.map((token) => {
|
|
46
|
+
const { start = -1, end = -1 } = token;
|
|
47
|
+
return Number.isInteger(start) && Number.isInteger(end) && start >= 0 && end > start && end <= text.length ? { ...token, start, end } : { ...token, start: -1, end: -1 };
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function tokenOffsets(text, tokenizer) {
|
|
51
|
+
const { input_ids } = tokenizer(text, { return_tensor: false, truncation: true });
|
|
46
52
|
let cursor = 0;
|
|
47
|
-
|
|
48
|
-
const
|
|
53
|
+
return input_ids.map((id) => {
|
|
54
|
+
const word = tokenizer.decode([id], { skip_special_tokens: true });
|
|
55
|
+
const surface = word.startsWith("##") ? word.slice(2) : word;
|
|
56
|
+
if (!surface) return { start: -1, end: -1 };
|
|
49
57
|
const start = text.indexOf(surface, cursor);
|
|
50
|
-
if (start < 0) {
|
|
51
|
-
placed.push({ ...t, start: -1, end: -1 });
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
58
|
+
if (start < 0) return { start: -1, end: -1 };
|
|
54
59
|
const end = start + surface.length;
|
|
55
|
-
placed.push({ ...t, start, end });
|
|
56
60
|
cursor = end;
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
return { start, end };
|
|
62
|
+
});
|
|
59
63
|
}
|
|
60
64
|
function aggregateTokens(tokens, text, tagMap, minScore) {
|
|
61
65
|
const placed = placeTokens(tokens, text);
|
|
@@ -115,7 +119,14 @@ function createTransformersNerDetector(options = {}) {
|
|
|
115
119
|
if (!text) return [];
|
|
116
120
|
const classify = await load();
|
|
117
121
|
const tokens = await classify(text);
|
|
118
|
-
|
|
122
|
+
if (!tokens.length) return [];
|
|
123
|
+
const offsets = tokenOffsets(text, classify.tokenizer);
|
|
124
|
+
return aggregateTokens(
|
|
125
|
+
tokens.map((token) => ({ ...token, ...offsets[token.index] })),
|
|
126
|
+
text,
|
|
127
|
+
tagMap,
|
|
128
|
+
minScore
|
|
129
|
+
);
|
|
119
130
|
}
|
|
120
131
|
};
|
|
121
132
|
}
|
|
@@ -54,13 +54,10 @@ interface RawToken {
|
|
|
54
54
|
score: number;
|
|
55
55
|
index: number;
|
|
56
56
|
word: string;
|
|
57
|
+
start?: number;
|
|
58
|
+
end?: number;
|
|
57
59
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Aggregate B-/I- subword tokens into whole-entity spans. A new entity starts
|
|
60
|
-
* on a `B-` tag or a tag change; contiguous `I-` tokens (and WordPiece "##"
|
|
61
|
-
* continuations) of the same base tag extend it. (The SDK additionally snaps
|
|
62
|
-
* spans to word boundaries, so dropped trailing subwords are recovered there.)
|
|
63
|
-
*/
|
|
60
|
+
/** Aggregate classified tokens with character offsets into whole-entity spans. */
|
|
64
61
|
declare function aggregateTokens(tokens: RawToken[], text: string, tagMap: Record<string, string | undefined>, minScore: number): PiiSpan[];
|
|
65
62
|
/**
|
|
66
63
|
* Create a Transformers.js-backed {@link NerDetector}. The returned detector
|
|
@@ -54,13 +54,10 @@ interface RawToken {
|
|
|
54
54
|
score: number;
|
|
55
55
|
index: number;
|
|
56
56
|
word: string;
|
|
57
|
+
start?: number;
|
|
58
|
+
end?: number;
|
|
57
59
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Aggregate B-/I- subword tokens into whole-entity spans. A new entity starts
|
|
60
|
-
* on a `B-` tag or a tag change; contiguous `I-` tokens (and WordPiece "##"
|
|
61
|
-
* continuations) of the same base tag extend it. (The SDK additionally snaps
|
|
62
|
-
* spans to word boundaries, so dropped trailing subwords are recovered there.)
|
|
63
|
-
*/
|
|
60
|
+
/** Aggregate classified tokens with character offsets into whole-entity spans. */
|
|
64
61
|
declare function aggregateTokens(tokens: RawToken[], text: string, tagMap: Record<string, string | undefined>, minScore: number): PiiSpan[];
|
|
65
62
|
/**
|
|
66
63
|
* Create a Transformers.js-backed {@link NerDetector}. The returned detector
|
|
@@ -7,20 +7,24 @@ var DEFAULT_TAG_MAP = {
|
|
|
7
7
|
MISC: void 0
|
|
8
8
|
};
|
|
9
9
|
function placeTokens(tokens, text) {
|
|
10
|
-
|
|
10
|
+
return tokens.map((token) => {
|
|
11
|
+
const { start = -1, end = -1 } = token;
|
|
12
|
+
return Number.isInteger(start) && Number.isInteger(end) && start >= 0 && end > start && end <= text.length ? { ...token, start, end } : { ...token, start: -1, end: -1 };
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function tokenOffsets(text, tokenizer) {
|
|
16
|
+
const { input_ids } = tokenizer(text, { return_tensor: false, truncation: true });
|
|
11
17
|
let cursor = 0;
|
|
12
|
-
|
|
13
|
-
const
|
|
18
|
+
return input_ids.map((id) => {
|
|
19
|
+
const word = tokenizer.decode([id], { skip_special_tokens: true });
|
|
20
|
+
const surface = word.startsWith("##") ? word.slice(2) : word;
|
|
21
|
+
if (!surface) return { start: -1, end: -1 };
|
|
14
22
|
const start = text.indexOf(surface, cursor);
|
|
15
|
-
if (start < 0) {
|
|
16
|
-
placed.push({ ...t, start: -1, end: -1 });
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
23
|
+
if (start < 0) return { start: -1, end: -1 };
|
|
19
24
|
const end = start + surface.length;
|
|
20
|
-
placed.push({ ...t, start, end });
|
|
21
25
|
cursor = end;
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
return { start, end };
|
|
27
|
+
});
|
|
24
28
|
}
|
|
25
29
|
function aggregateTokens(tokens, text, tagMap, minScore) {
|
|
26
30
|
const placed = placeTokens(tokens, text);
|
|
@@ -80,7 +84,14 @@ function createTransformersNerDetector(options = {}) {
|
|
|
80
84
|
if (!text) return [];
|
|
81
85
|
const classify = await load();
|
|
82
86
|
const tokens = await classify(text);
|
|
83
|
-
|
|
87
|
+
if (!tokens.length) return [];
|
|
88
|
+
const offsets = tokenOffsets(text, classify.tokenizer);
|
|
89
|
+
return aggregateTokens(
|
|
90
|
+
tokens.map((token) => ({ ...token, ...offsets[token.index] })),
|
|
91
|
+
text,
|
|
92
|
+
tagMap,
|
|
93
|
+
minScore
|
|
94
|
+
);
|
|
84
95
|
}
|
|
85
96
|
};
|
|
86
97
|
}
|
package/dist/react/index.cjs
CHANGED
|
@@ -20374,6 +20374,52 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
20374
20374
|
trustTier: raw.trust_tier ?? null
|
|
20375
20375
|
}));
|
|
20376
20376
|
}
|
|
20377
|
+
async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
20378
|
+
assertVaultScopeForSweep(ctx);
|
|
20379
|
+
const byId = new Map(candidates.map((candidate) => [candidate.uniqueId, candidate]));
|
|
20380
|
+
const ids = Array.from(byId.keys());
|
|
20381
|
+
const changed = /* @__PURE__ */ new Set();
|
|
20382
|
+
const CHUNK = 500;
|
|
20383
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
20384
|
+
let applied = [];
|
|
20385
|
+
try {
|
|
20386
|
+
await ctx.database.write(async () => {
|
|
20387
|
+
await assertCanWrite2(ctx);
|
|
20388
|
+
const records = await ctx.vaultMemoryCollection.query(
|
|
20389
|
+
import_watermelondb24.Q.where("id", import_watermelondb24.Q.oneOf(ids.slice(i, i + CHUNK))),
|
|
20390
|
+
...ctx.userId !== void 0 ? [import_watermelondb24.Q.where("user_id", ctx.userId)] : []
|
|
20391
|
+
).fetch();
|
|
20392
|
+
const eligible = records.filter((record2) => {
|
|
20393
|
+
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
20394
|
+
if (opts.transition === "delete") {
|
|
20395
|
+
return record2.archivedAt !== null && opts.now - record2.archivedAt > opts.hardDeleteWindowMs;
|
|
20396
|
+
}
|
|
20397
|
+
const candidate = byId.get(record2.id);
|
|
20398
|
+
return record2.archivedAt === null && record2.updatedAt.getTime() === candidate.updatedAt && (record2.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
20399
|
+
});
|
|
20400
|
+
const prepared = eligible.map(
|
|
20401
|
+
(record2) => record2.prepareUpdate((row) => {
|
|
20402
|
+
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
20403
|
+
else row._setRaw("is_deleted", true);
|
|
20404
|
+
})
|
|
20405
|
+
);
|
|
20406
|
+
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
20407
|
+
applied = eligible.map((record2) => record2.id);
|
|
20408
|
+
});
|
|
20409
|
+
} catch {
|
|
20410
|
+
continue;
|
|
20411
|
+
}
|
|
20412
|
+
for (const id2 of applied) changed.add(id2);
|
|
20413
|
+
if (opts.transition === "delete" && ctx.entityCtx) {
|
|
20414
|
+
try {
|
|
20415
|
+
await unlinkMemoryEntitiesOp(ctx.entityCtx, applied);
|
|
20416
|
+
} catch {
|
|
20417
|
+
continue;
|
|
20418
|
+
}
|
|
20419
|
+
}
|
|
20420
|
+
}
|
|
20421
|
+
return changed;
|
|
20422
|
+
}
|
|
20377
20423
|
async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
20378
20424
|
try {
|
|
20379
20425
|
const record2 = await ctx.vaultMemoryCollection.find(id2);
|
|
@@ -25444,25 +25490,8 @@ function isBorderline(input) {
|
|
|
25444
25490
|
function vaultDecayBackend(vaultCtx) {
|
|
25445
25491
|
return {
|
|
25446
25492
|
candidates: () => getDecayCandidatesRawOp(vaultCtx),
|
|
25447
|
-
archive:
|
|
25448
|
-
|
|
25449
|
-
for (const c of rows) {
|
|
25450
|
-
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
25451
|
-
now,
|
|
25452
|
-
expectedUpdatedAt: c.updatedAt,
|
|
25453
|
-
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
25454
|
-
});
|
|
25455
|
-
if (ok) archived.add(c.uniqueId);
|
|
25456
|
-
}
|
|
25457
|
-
return archived;
|
|
25458
|
-
},
|
|
25459
|
-
hardDelete: async (rows, deleteOptions) => {
|
|
25460
|
-
const deleted = /* @__PURE__ */ new Set();
|
|
25461
|
-
for (const c of rows) {
|
|
25462
|
-
if (await hardDeleteDecayedOp(vaultCtx, c.uniqueId, deleteOptions)) deleted.add(c.uniqueId);
|
|
25463
|
-
}
|
|
25464
|
-
return deleted;
|
|
25465
|
-
}
|
|
25493
|
+
archive: (rows, now) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "archive", now }),
|
|
25494
|
+
hardDelete: (rows, deleteOptions) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "delete", ...deleteOptions })
|
|
25466
25495
|
};
|
|
25467
25496
|
}
|
|
25468
25497
|
function createDecaySweeper(options) {
|
|
@@ -27490,6 +27519,7 @@ function createLocalMemoryStore(options) {
|
|
|
27490
27519
|
"trust_tier",
|
|
27491
27520
|
"superseded_by",
|
|
27492
27521
|
"visibility",
|
|
27522
|
+
"twin_opt_in",
|
|
27493
27523
|
"published_at",
|
|
27494
27524
|
"geohash",
|
|
27495
27525
|
"topics",
|
|
@@ -28681,6 +28711,7 @@ function subscriptionState({ memory, version }) {
|
|
|
28681
28711
|
memory.event_time_kind,
|
|
28682
28712
|
memory.trust_tier,
|
|
28683
28713
|
memory.visibility,
|
|
28714
|
+
memory.twin_opt_in,
|
|
28684
28715
|
memory.published_at,
|
|
28685
28716
|
memory.geohash,
|
|
28686
28717
|
memory.topics,
|
package/dist/react/index.mjs
CHANGED
|
@@ -18500,6 +18500,52 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
18500
18500
|
trustTier: raw.trust_tier ?? null
|
|
18501
18501
|
}));
|
|
18502
18502
|
}
|
|
18503
|
+
async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
18504
|
+
assertVaultScopeForSweep(ctx);
|
|
18505
|
+
const byId = new Map(candidates.map((candidate) => [candidate.uniqueId, candidate]));
|
|
18506
|
+
const ids = Array.from(byId.keys());
|
|
18507
|
+
const changed = /* @__PURE__ */ new Set();
|
|
18508
|
+
const CHUNK = 500;
|
|
18509
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
18510
|
+
let applied = [];
|
|
18511
|
+
try {
|
|
18512
|
+
await ctx.database.write(async () => {
|
|
18513
|
+
await assertCanWrite2(ctx);
|
|
18514
|
+
const records = await ctx.vaultMemoryCollection.query(
|
|
18515
|
+
Q9.where("id", Q9.oneOf(ids.slice(i, i + CHUNK))),
|
|
18516
|
+
...ctx.userId !== void 0 ? [Q9.where("user_id", ctx.userId)] : []
|
|
18517
|
+
).fetch();
|
|
18518
|
+
const eligible = records.filter((record2) => {
|
|
18519
|
+
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
18520
|
+
if (opts.transition === "delete") {
|
|
18521
|
+
return record2.archivedAt !== null && opts.now - record2.archivedAt > opts.hardDeleteWindowMs;
|
|
18522
|
+
}
|
|
18523
|
+
const candidate = byId.get(record2.id);
|
|
18524
|
+
return record2.archivedAt === null && record2.updatedAt.getTime() === candidate.updatedAt && (record2.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
18525
|
+
});
|
|
18526
|
+
const prepared = eligible.map(
|
|
18527
|
+
(record2) => record2.prepareUpdate((row) => {
|
|
18528
|
+
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
18529
|
+
else row._setRaw("is_deleted", true);
|
|
18530
|
+
})
|
|
18531
|
+
);
|
|
18532
|
+
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
18533
|
+
applied = eligible.map((record2) => record2.id);
|
|
18534
|
+
});
|
|
18535
|
+
} catch {
|
|
18536
|
+
continue;
|
|
18537
|
+
}
|
|
18538
|
+
for (const id2 of applied) changed.add(id2);
|
|
18539
|
+
if (opts.transition === "delete" && ctx.entityCtx) {
|
|
18540
|
+
try {
|
|
18541
|
+
await unlinkMemoryEntitiesOp(ctx.entityCtx, applied);
|
|
18542
|
+
} catch {
|
|
18543
|
+
continue;
|
|
18544
|
+
}
|
|
18545
|
+
}
|
|
18546
|
+
}
|
|
18547
|
+
return changed;
|
|
18548
|
+
}
|
|
18503
18549
|
async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
18504
18550
|
try {
|
|
18505
18551
|
const record2 = await ctx.vaultMemoryCollection.find(id2);
|
|
@@ -23536,25 +23582,8 @@ function isBorderline(input) {
|
|
|
23536
23582
|
function vaultDecayBackend(vaultCtx) {
|
|
23537
23583
|
return {
|
|
23538
23584
|
candidates: () => getDecayCandidatesRawOp(vaultCtx),
|
|
23539
|
-
archive:
|
|
23540
|
-
|
|
23541
|
-
for (const c of rows) {
|
|
23542
|
-
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
23543
|
-
now,
|
|
23544
|
-
expectedUpdatedAt: c.updatedAt,
|
|
23545
|
-
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
23546
|
-
});
|
|
23547
|
-
if (ok) archived.add(c.uniqueId);
|
|
23548
|
-
}
|
|
23549
|
-
return archived;
|
|
23550
|
-
},
|
|
23551
|
-
hardDelete: async (rows, deleteOptions) => {
|
|
23552
|
-
const deleted = /* @__PURE__ */ new Set();
|
|
23553
|
-
for (const c of rows) {
|
|
23554
|
-
if (await hardDeleteDecayedOp(vaultCtx, c.uniqueId, deleteOptions)) deleted.add(c.uniqueId);
|
|
23555
|
-
}
|
|
23556
|
-
return deleted;
|
|
23557
|
-
}
|
|
23585
|
+
archive: (rows, now) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "archive", now }),
|
|
23586
|
+
hardDelete: (rows, deleteOptions) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "delete", ...deleteOptions })
|
|
23558
23587
|
};
|
|
23559
23588
|
}
|
|
23560
23589
|
function createDecaySweeper(options) {
|
|
@@ -25567,6 +25596,7 @@ function createLocalMemoryStore(options) {
|
|
|
25567
25596
|
"trust_tier",
|
|
25568
25597
|
"superseded_by",
|
|
25569
25598
|
"visibility",
|
|
25599
|
+
"twin_opt_in",
|
|
25570
25600
|
"published_at",
|
|
25571
25601
|
"geohash",
|
|
25572
25602
|
"topics",
|
|
@@ -26753,6 +26783,7 @@ function subscriptionState({ memory, version }) {
|
|
|
26753
26783
|
memory.event_time_kind,
|
|
26754
26784
|
memory.trust_tier,
|
|
26755
26785
|
memory.visibility,
|
|
26786
|
+
memory.twin_opt_in,
|
|
26756
26787
|
memory.published_at,
|
|
26757
26788
|
memory.geohash,
|
|
26758
26789
|
memory.topics,
|
package/dist/server/index.cjs
CHANGED
|
@@ -29987,6 +29987,52 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
29987
29987
|
trustTier: raw.trust_tier ?? null
|
|
29988
29988
|
}));
|
|
29989
29989
|
}
|
|
29990
|
+
async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
29991
|
+
assertVaultScopeForSweep(ctx);
|
|
29992
|
+
const byId = new Map(candidates.map((candidate) => [candidate.uniqueId, candidate]));
|
|
29993
|
+
const ids = Array.from(byId.keys());
|
|
29994
|
+
const changed = /* @__PURE__ */ new Set();
|
|
29995
|
+
const CHUNK = 500;
|
|
29996
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
29997
|
+
let applied = [];
|
|
29998
|
+
try {
|
|
29999
|
+
await ctx.database.write(async () => {
|
|
30000
|
+
await assertCanWrite2(ctx);
|
|
30001
|
+
const records = await ctx.vaultMemoryCollection.query(
|
|
30002
|
+
import_watermelondb19.Q.where("id", import_watermelondb19.Q.oneOf(ids.slice(i, i + CHUNK))),
|
|
30003
|
+
...ctx.userId !== void 0 ? [import_watermelondb19.Q.where("user_id", ctx.userId)] : []
|
|
30004
|
+
).fetch();
|
|
30005
|
+
const eligible = records.filter((record) => {
|
|
30006
|
+
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
|
|
30007
|
+
if (opts.transition === "delete") {
|
|
30008
|
+
return record.archivedAt !== null && opts.now - record.archivedAt > opts.hardDeleteWindowMs;
|
|
30009
|
+
}
|
|
30010
|
+
const candidate = byId.get(record.id);
|
|
30011
|
+
return record.archivedAt === null && record.updatedAt.getTime() === candidate.updatedAt && (record.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
30012
|
+
});
|
|
30013
|
+
const prepared = eligible.map(
|
|
30014
|
+
(record) => record.prepareUpdate((row) => {
|
|
30015
|
+
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
30016
|
+
else row._setRaw("is_deleted", true);
|
|
30017
|
+
})
|
|
30018
|
+
);
|
|
30019
|
+
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
30020
|
+
applied = eligible.map((record) => record.id);
|
|
30021
|
+
});
|
|
30022
|
+
} catch {
|
|
30023
|
+
continue;
|
|
30024
|
+
}
|
|
30025
|
+
for (const id of applied) changed.add(id);
|
|
30026
|
+
if (opts.transition === "delete" && ctx.entityCtx) {
|
|
30027
|
+
try {
|
|
30028
|
+
await unlinkMemoryEntitiesOp(ctx.entityCtx, applied);
|
|
30029
|
+
} catch {
|
|
30030
|
+
continue;
|
|
30031
|
+
}
|
|
30032
|
+
}
|
|
30033
|
+
}
|
|
30034
|
+
return changed;
|
|
30035
|
+
}
|
|
29990
30036
|
async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
29991
30037
|
try {
|
|
29992
30038
|
const record = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -34752,25 +34798,8 @@ function isBorderline(input) {
|
|
|
34752
34798
|
function vaultDecayBackend(vaultCtx) {
|
|
34753
34799
|
return {
|
|
34754
34800
|
candidates: () => getDecayCandidatesRawOp(vaultCtx),
|
|
34755
|
-
archive:
|
|
34756
|
-
|
|
34757
|
-
for (const c of rows) {
|
|
34758
|
-
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
34759
|
-
now,
|
|
34760
|
-
expectedUpdatedAt: c.updatedAt,
|
|
34761
|
-
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
34762
|
-
});
|
|
34763
|
-
if (ok) archived.add(c.uniqueId);
|
|
34764
|
-
}
|
|
34765
|
-
return archived;
|
|
34766
|
-
},
|
|
34767
|
-
hardDelete: async (rows, deleteOptions) => {
|
|
34768
|
-
const deleted = /* @__PURE__ */ new Set();
|
|
34769
|
-
for (const c of rows) {
|
|
34770
|
-
if (await hardDeleteDecayedOp(vaultCtx, c.uniqueId, deleteOptions)) deleted.add(c.uniqueId);
|
|
34771
|
-
}
|
|
34772
|
-
return deleted;
|
|
34773
|
-
}
|
|
34801
|
+
archive: (rows, now) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "archive", now }),
|
|
34802
|
+
hardDelete: (rows, deleteOptions) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "delete", ...deleteOptions })
|
|
34774
34803
|
};
|
|
34775
34804
|
}
|
|
34776
34805
|
function createDecaySweeper(options) {
|
|
@@ -36798,6 +36827,7 @@ function createLocalMemoryStore(options) {
|
|
|
36798
36827
|
"trust_tier",
|
|
36799
36828
|
"superseded_by",
|
|
36800
36829
|
"visibility",
|
|
36830
|
+
"twin_opt_in",
|
|
36801
36831
|
"published_at",
|
|
36802
36832
|
"geohash",
|
|
36803
36833
|
"topics",
|
package/dist/server/index.mjs
CHANGED
|
@@ -28245,6 +28245,52 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
28245
28245
|
trustTier: raw.trust_tier ?? null
|
|
28246
28246
|
}));
|
|
28247
28247
|
}
|
|
28248
|
+
async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
28249
|
+
assertVaultScopeForSweep(ctx);
|
|
28250
|
+
const byId = new Map(candidates.map((candidate) => [candidate.uniqueId, candidate]));
|
|
28251
|
+
const ids = Array.from(byId.keys());
|
|
28252
|
+
const changed = /* @__PURE__ */ new Set();
|
|
28253
|
+
const CHUNK = 500;
|
|
28254
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
28255
|
+
let applied = [];
|
|
28256
|
+
try {
|
|
28257
|
+
await ctx.database.write(async () => {
|
|
28258
|
+
await assertCanWrite2(ctx);
|
|
28259
|
+
const records = await ctx.vaultMemoryCollection.query(
|
|
28260
|
+
import_watermelondb19.Q.where("id", import_watermelondb19.Q.oneOf(ids.slice(i, i + CHUNK))),
|
|
28261
|
+
...ctx.userId !== void 0 ? [import_watermelondb19.Q.where("user_id", ctx.userId)] : []
|
|
28262
|
+
).fetch();
|
|
28263
|
+
const eligible = records.filter((record) => {
|
|
28264
|
+
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
|
|
28265
|
+
if (opts.transition === "delete") {
|
|
28266
|
+
return record.archivedAt !== null && opts.now - record.archivedAt > opts.hardDeleteWindowMs;
|
|
28267
|
+
}
|
|
28268
|
+
const candidate = byId.get(record.id);
|
|
28269
|
+
return record.archivedAt === null && record.updatedAt.getTime() === candidate.updatedAt && (record.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
28270
|
+
});
|
|
28271
|
+
const prepared = eligible.map(
|
|
28272
|
+
(record) => record.prepareUpdate((row) => {
|
|
28273
|
+
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
28274
|
+
else row._setRaw("is_deleted", true);
|
|
28275
|
+
})
|
|
28276
|
+
);
|
|
28277
|
+
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
28278
|
+
applied = eligible.map((record) => record.id);
|
|
28279
|
+
});
|
|
28280
|
+
} catch {
|
|
28281
|
+
continue;
|
|
28282
|
+
}
|
|
28283
|
+
for (const id of applied) changed.add(id);
|
|
28284
|
+
if (opts.transition === "delete" && ctx.entityCtx) {
|
|
28285
|
+
try {
|
|
28286
|
+
await unlinkMemoryEntitiesOp(ctx.entityCtx, applied);
|
|
28287
|
+
} catch {
|
|
28288
|
+
continue;
|
|
28289
|
+
}
|
|
28290
|
+
}
|
|
28291
|
+
}
|
|
28292
|
+
return changed;
|
|
28293
|
+
}
|
|
28248
28294
|
async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
28249
28295
|
try {
|
|
28250
28296
|
const record = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -32982,25 +33028,8 @@ function isBorderline(input) {
|
|
|
32982
33028
|
function vaultDecayBackend(vaultCtx) {
|
|
32983
33029
|
return {
|
|
32984
33030
|
candidates: () => getDecayCandidatesRawOp(vaultCtx),
|
|
32985
|
-
archive:
|
|
32986
|
-
|
|
32987
|
-
for (const c of rows) {
|
|
32988
|
-
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
32989
|
-
now,
|
|
32990
|
-
expectedUpdatedAt: c.updatedAt,
|
|
32991
|
-
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
32992
|
-
});
|
|
32993
|
-
if (ok) archived.add(c.uniqueId);
|
|
32994
|
-
}
|
|
32995
|
-
return archived;
|
|
32996
|
-
},
|
|
32997
|
-
hardDelete: async (rows, deleteOptions) => {
|
|
32998
|
-
const deleted = /* @__PURE__ */ new Set();
|
|
32999
|
-
for (const c of rows) {
|
|
33000
|
-
if (await hardDeleteDecayedOp(vaultCtx, c.uniqueId, deleteOptions)) deleted.add(c.uniqueId);
|
|
33001
|
-
}
|
|
33002
|
-
return deleted;
|
|
33003
|
-
}
|
|
33031
|
+
archive: (rows, now) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "archive", now }),
|
|
33032
|
+
hardDelete: (rows, deleteOptions) => applyDecayTransitionsOp(vaultCtx, rows, { transition: "delete", ...deleteOptions })
|
|
33004
33033
|
};
|
|
33005
33034
|
}
|
|
33006
33035
|
function createDecaySweeper(options) {
|
|
@@ -35013,6 +35042,7 @@ function createLocalMemoryStore(options) {
|
|
|
35013
35042
|
"trust_tier",
|
|
35014
35043
|
"superseded_by",
|
|
35015
35044
|
"visibility",
|
|
35045
|
+
"twin_opt_in",
|
|
35016
35046
|
"published_at",
|
|
35017
35047
|
"geohash",
|
|
35018
35048
|
"topics",
|