videobook-engine 5.3.2 → 5.4.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/README.md +6 -0
- package/dist/catalog-metadata.d.ts +1 -1
- package/dist/catalog-metadata.js +1 -1
- package/dist/domain.js +15 -5
- package/dist/domain.js.map +1 -1
- package/dist/engine-types.d.ts +140 -1
- package/dist/engine-types.d.ts.map +1 -1
- package/dist/engine-types.js.map +1 -1
- package/dist/engine.d.ts +21 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +3 -0
- package/dist/engine.js.map +1 -1
- package/dist/fork.d.ts +3 -4
- package/dist/fork.d.ts.map +1 -1
- package/dist/fork.js +4 -4
- package/dist/fork.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/merge-policy.d.ts +3 -4
- package/dist/merge-policy.d.ts.map +1 -1
- package/dist/merge-policy.js +5 -4
- package/dist/merge-policy.js.map +1 -1
- package/dist/migrate-tags-v24.d.ts +12 -0
- package/dist/migrate-tags-v24.d.ts.map +1 -0
- package/dist/migrate-tags-v24.js +40 -0
- package/dist/migrate-tags-v24.js.map +1 -0
- package/dist/mvp-contracts.d.ts +2 -2
- package/dist/mvp-contracts.js +1 -1
- package/dist/schema.d.ts +3 -2
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +59 -0
- package/dist/schema.js.map +1 -1
- package/dist/store.d.ts +6 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +150 -54
- package/dist/store.js.map +1 -1
- package/dist/tag-merge.d.ts +4 -0
- package/dist/tag-merge.d.ts.map +1 -0
- package/dist/tag-merge.js +85 -0
- package/dist/tag-merge.js.map +1 -0
- package/dist/tag-queries.d.ts +30 -0
- package/dist/tag-queries.d.ts.map +1 -0
- package/dist/tag-queries.js +313 -0
- package/dist/tag-queries.js.map +1 -0
- package/dist/tag-rows.d.ts +36 -0
- package/dist/tag-rows.d.ts.map +1 -0
- package/dist/tag-rows.js +48 -0
- package/dist/tag-rows.js.map +1 -0
- package/dist/tag-transfer.d.ts +26 -0
- package/dist/tag-transfer.d.ts.map +1 -0
- package/dist/tag-transfer.js +341 -0
- package/dist/tag-transfer.js.map +1 -0
- package/dist/tag-validation.d.ts +15 -0
- package/dist/tag-validation.d.ts.map +1 -0
- package/dist/tag-validation.js +36 -0
- package/dist/tag-validation.js.map +1 -0
- package/dist/tag-values.d.ts +68 -0
- package/dist/tag-values.d.ts.map +1 -0
- package/dist/tag-values.js +107 -0
- package/dist/tag-values.js.map +1 -0
- package/dist/tags.d.ts +44 -0
- package/dist/tags.d.ts.map +1 -0
- package/dist/tags.js +488 -0
- package/dist/tags.js.map +1 -0
- package/docs/doltlite-staging.md +35 -15
- package/docs/edit-performance.md +2 -4
- package/docs/engine-layout.md +92 -4
- package/docs/mvp-prd.md +2 -1
- package/docs/release-evidence.md +74 -35
- package/docs/temporal-search-performance.md +4 -6
- package/fixtures/v5/contract-fixtures.json +3 -3
- package/package.json +7 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAGhB,oBAAoB,EAEpB,WAAW,EACX,wBAAwB,EACxB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAA0B,MAAM,cAAc,CAAC;AAMrE,OAAO,KAAK,EAEV,gBAAgB,EAChB,QAAQ,EACT,MAAM,iBAAiB,CAAC;AASzB,iDAAiD;AACjD,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAiCtC,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa;uBAQ7B,MAAM,KAAG,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC;4BAGlD,SAAS,MAAM,EAAE,KAC7B,MAAM,CAAC,gBAAgB,EAAE,EAAE,WAAW,CAAC;sBAG5B,MAAM,OACb,QAAQ,KACZ,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;0BAGnC,MAAM,QACZ,SAAS,QAAQ,EAAE,KACxB,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;yBAGnC,MAAM,OACb,gBAAgB,KACpB,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;0BAGnC,MAAM,OACb,gBAAgB,KACpB,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;;+BAIjC,MAAM,KACjB,MAAM,CAAC,oBAAoB,GAAG,SAAS,EAAE,WAAW,CAAC;yBAG/C,wBAAwB,KAC9B,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;;;;;;;;aAlB/C,CAAC;;;EAsBR"}
|
package/dist/tags.js
ADDED
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset tags: durable automatic and user-managed tagging.
|
|
3
|
+
*
|
|
4
|
+
* The engine owns state, normalization, transactions and provenance; the
|
|
5
|
+
* consumer owns inference, scheduling and vocabulary. Three rules shape
|
|
6
|
+
* everything here:
|
|
7
|
+
*
|
|
8
|
+
* 1. Semantic identity is (facet, canonical key). Two facets carrying the
|
|
9
|
+
* same word stay distinct assignments.
|
|
10
|
+
* 2. Manual intent outranks analysis. An automatic snapshot replaces only
|
|
11
|
+
* the automatic rows; it can never add, drop or relabel a manual row,
|
|
12
|
+
* and it can never clear a dismissal.
|
|
13
|
+
* 3. Automatic output is fenced to the content it described. A snapshot
|
|
14
|
+
* records the analyzed source hash and a per-artifact generation, so a
|
|
15
|
+
* late result cannot overwrite a newer one and tags for replaced
|
|
16
|
+
* content drop out of the effective set instead of lying.
|
|
17
|
+
*/
|
|
18
|
+
import { ok } from "./engine-types.js";
|
|
19
|
+
import { resultOf, syncResultOf } from "./context.js";
|
|
20
|
+
import { EngineFault } from "./store.js";
|
|
21
|
+
import { createTagQueriesApi } from "./tag-queries.js";
|
|
22
|
+
import { automaticTagsMatch, compareTags, snapshotMatches } from "./tag-rows.js";
|
|
23
|
+
import { createTagTransferApi } from "./tag-transfer.js";
|
|
24
|
+
import { normalizeAutomaticTags } from "./tag-validation.js";
|
|
25
|
+
import { MANUAL_TAGS_PER_ARTIFACT_MAX, TAG_DISMISSALS_PER_ARTIFACT_MAX, normalizeTagIdentity, normalizeTagList, tagIdentity, } from "./tag-values.js";
|
|
26
|
+
/** Artifacts a single batched read may cover. */
|
|
27
|
+
export const TAG_READ_BATCH_MAX = 500;
|
|
28
|
+
const READ_CHUNK = 200;
|
|
29
|
+
export function createTagsApi(context) {
|
|
30
|
+
const queries = createTagQueriesApi(context);
|
|
31
|
+
const transfer = createTagTransferApi(context, (artifactId) => tagState(context, artifactId));
|
|
32
|
+
return {
|
|
33
|
+
...queries,
|
|
34
|
+
...transfer,
|
|
35
|
+
read: (artifactId) => syncResultOf(() => readTagState(context, artifactId)),
|
|
36
|
+
readMany: (artifactIds) => syncResultOf(() => readTagStates(context, artifactIds)),
|
|
37
|
+
add: (artifactId, tag) => addManualTags(context, artifactId, [tag]),
|
|
38
|
+
addMany: (artifactId, tags) => addManualTags(context, artifactId, tags),
|
|
39
|
+
remove: (artifactId, tag) => removeTag(context, artifactId, tag),
|
|
40
|
+
restore: (artifactId, tag) => restoreTag(context, artifactId, tag),
|
|
41
|
+
automatic: {
|
|
42
|
+
snapshot: (artifactId) => syncResultOf(() => readSnapshot(context, artifactId)),
|
|
43
|
+
replace: (input) => replaceAutomaticTags(context, input),
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------- reads
|
|
48
|
+
function readTagState(context, artifactReference) {
|
|
49
|
+
const artifact = context.artifactRow(artifactReference);
|
|
50
|
+
return tagState(context, artifact.artifact_id);
|
|
51
|
+
}
|
|
52
|
+
function readTagStates(context, artifactReferences) {
|
|
53
|
+
if (artifactReferences.length > TAG_READ_BATCH_MAX) {
|
|
54
|
+
throw new Error(`Tag reads must cover at most ${TAG_READ_BATCH_MAX} artifacts; received ${artifactReferences.length}`);
|
|
55
|
+
}
|
|
56
|
+
const artifactIds = artifactReferences.map((reference) => context.artifactRow(reference).artifact_id);
|
|
57
|
+
const tags = chunkedRows(context, artifactIds, (placeholders) => `SELECT artifact_id, origin, facet, tag_key, label, entity_id, created_at
|
|
58
|
+
FROM artifact_tags
|
|
59
|
+
WHERE artifact_id IN (${placeholders})
|
|
60
|
+
ORDER BY artifact_id, facet, tag_key`);
|
|
61
|
+
const dismissals = chunkedRows(context, artifactIds, (placeholders) => `SELECT artifact_id, facet, tag_key, label, dismissed_at
|
|
62
|
+
FROM artifact_tag_dismissals
|
|
63
|
+
WHERE artifact_id IN (${placeholders})
|
|
64
|
+
ORDER BY artifact_id, facet, tag_key`);
|
|
65
|
+
const snapshots = chunkedRows(context, artifactIds, (placeholders) => `SELECT artifact_id, source_hash, generator, model, extractor_version,
|
|
66
|
+
tag_count, generation, analyzed_at
|
|
67
|
+
FROM artifact_tag_snapshots
|
|
68
|
+
WHERE artifact_id IN (${placeholders})`);
|
|
69
|
+
const snapshotByArtifact = new Map(snapshots.map((row) => [row.artifact_id, row]));
|
|
70
|
+
const liveHashes = artifactFileHashes(context, artifactIds);
|
|
71
|
+
return artifactIds.map((artifactId) => assembleState(artifactId, tags.filter((row) => row.artifact_id === artifactId), dismissals.filter((row) => row.artifact_id === artifactId), snapshotByArtifact.get(artifactId), liveHashes.get(artifactId) ?? new Set()));
|
|
72
|
+
}
|
|
73
|
+
function tagState(context, artifactId) {
|
|
74
|
+
const tags = context.store.db
|
|
75
|
+
.prepare(`SELECT artifact_id, origin, facet, tag_key, label, entity_id, created_at
|
|
76
|
+
FROM artifact_tags
|
|
77
|
+
WHERE artifact_id=?
|
|
78
|
+
ORDER BY facet, tag_key`)
|
|
79
|
+
.all(artifactId);
|
|
80
|
+
const dismissals = context.store.db
|
|
81
|
+
.prepare(`SELECT artifact_id, facet, tag_key, label, dismissed_at
|
|
82
|
+
FROM artifact_tag_dismissals
|
|
83
|
+
WHERE artifact_id=?
|
|
84
|
+
ORDER BY facet, tag_key`)
|
|
85
|
+
.all(artifactId);
|
|
86
|
+
const snapshot = snapshotRow(context, artifactId);
|
|
87
|
+
return assembleState(artifactId, tags, dismissals, snapshot, artifactFileHashes(context, [artifactId]).get(artifactId) ??
|
|
88
|
+
new Set());
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Effective tags: every manual assignment, plus automatic assignments that
|
|
92
|
+
* are neither dismissed nor stale, deduplicated on identity with the
|
|
93
|
+
* manual display label and ownership preferred.
|
|
94
|
+
*/
|
|
95
|
+
function assembleState(artifactId, tagRows, dismissalRows, snapshotRow, liveHashes) {
|
|
96
|
+
const dismissed = new Set(dismissalRows.map((row) => tagIdentity(row.facet, row.tag_key)));
|
|
97
|
+
const stale = snapshotRow !== undefined && !liveHashes.has(snapshotRow.source_hash);
|
|
98
|
+
const manual = tagRows
|
|
99
|
+
.filter((row) => row.origin === "manual")
|
|
100
|
+
.map((row) => assetTag(row));
|
|
101
|
+
const automatic = tagRows
|
|
102
|
+
.filter((row) => row.origin === "automatic")
|
|
103
|
+
.map((row) => ({
|
|
104
|
+
...assetTag(row),
|
|
105
|
+
dismissed: dismissed.has(tagIdentity(row.facet, row.tag_key)),
|
|
106
|
+
stale,
|
|
107
|
+
}));
|
|
108
|
+
const effective = [...manual];
|
|
109
|
+
const claimed = new Set(manual.map((tag) => tagIdentity(tag.facet, tag.key)));
|
|
110
|
+
for (const tag of automatic) {
|
|
111
|
+
if (tag.dismissed || tag.stale)
|
|
112
|
+
continue;
|
|
113
|
+
const identity = tagIdentity(tag.facet, tag.key);
|
|
114
|
+
if (claimed.has(identity))
|
|
115
|
+
continue;
|
|
116
|
+
claimed.add(identity);
|
|
117
|
+
effective.push({
|
|
118
|
+
facet: tag.facet,
|
|
119
|
+
key: tag.key,
|
|
120
|
+
label: tag.label,
|
|
121
|
+
origin: tag.origin,
|
|
122
|
+
...(tag.entityId ? { entityId: tag.entityId } : {}),
|
|
123
|
+
createdAt: tag.createdAt,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
effective.sort(compareTags);
|
|
127
|
+
return {
|
|
128
|
+
artifactId,
|
|
129
|
+
effective,
|
|
130
|
+
manual,
|
|
131
|
+
automatic,
|
|
132
|
+
dismissed: dismissalRows.map((row) => ({
|
|
133
|
+
facet: row.facet,
|
|
134
|
+
key: row.tag_key,
|
|
135
|
+
label: row.label,
|
|
136
|
+
dismissedAt: row.dismissed_at,
|
|
137
|
+
})),
|
|
138
|
+
...(snapshotRow
|
|
139
|
+
? { snapshot: snapshotFromRow(snapshotRow, stale) }
|
|
140
|
+
: {}),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function assetTag(row) {
|
|
144
|
+
return {
|
|
145
|
+
facet: row.facet,
|
|
146
|
+
key: row.tag_key,
|
|
147
|
+
label: row.label,
|
|
148
|
+
origin: row.origin,
|
|
149
|
+
...(row.entity_id ? { entityId: row.entity_id } : {}),
|
|
150
|
+
createdAt: row.created_at,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function readSnapshot(context, artifactReference) {
|
|
154
|
+
const artifact = context.artifactRow(artifactReference);
|
|
155
|
+
const row = snapshotRow(context, artifact.artifact_id);
|
|
156
|
+
if (!row)
|
|
157
|
+
return undefined;
|
|
158
|
+
const hashes = artifactFileHashes(context, [artifact.artifact_id]);
|
|
159
|
+
const live = hashes.get(artifact.artifact_id) ?? new Set();
|
|
160
|
+
return snapshotFromRow(row, !live.has(row.source_hash));
|
|
161
|
+
}
|
|
162
|
+
function snapshotRow(context, artifactId) {
|
|
163
|
+
return context.store.db
|
|
164
|
+
.prepare(`SELECT artifact_id, source_hash, generator, model, extractor_version,
|
|
165
|
+
tag_count, generation, analyzed_at
|
|
166
|
+
FROM artifact_tag_snapshots
|
|
167
|
+
WHERE artifact_id=?`)
|
|
168
|
+
.get(artifactId);
|
|
169
|
+
}
|
|
170
|
+
function snapshotFromRow(row, stale) {
|
|
171
|
+
return {
|
|
172
|
+
artifactId: row.artifact_id,
|
|
173
|
+
sourceHash: row.source_hash,
|
|
174
|
+
generator: row.generator,
|
|
175
|
+
...(row.model === null ? {} : { model: row.model }),
|
|
176
|
+
extractorVersion: row.extractor_version,
|
|
177
|
+
tagCount: row.tag_count,
|
|
178
|
+
generation: row.generation,
|
|
179
|
+
analyzedAt: row.analyzed_at,
|
|
180
|
+
stale,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Current content hashes per artifact. An automatic snapshot is stale once
|
|
185
|
+
* the hash it analyzed is no longer one of the artifact's files, which is
|
|
186
|
+
* how replaced originals drop their automatic tags without deleting the
|
|
187
|
+
* provenance that explains them.
|
|
188
|
+
*/
|
|
189
|
+
function artifactFileHashes(context, artifactIds) {
|
|
190
|
+
const rows = chunkedRows(context, artifactIds, (placeholders) => `SELECT artifact_id, object_hash FROM artifact_files
|
|
191
|
+
WHERE artifact_id IN (${placeholders})`);
|
|
192
|
+
const hashes = new Map();
|
|
193
|
+
for (const row of rows) {
|
|
194
|
+
const existing = hashes.get(row.artifact_id);
|
|
195
|
+
if (existing)
|
|
196
|
+
existing.add(row.object_hash);
|
|
197
|
+
else
|
|
198
|
+
hashes.set(row.artifact_id, new Set([row.object_hash]));
|
|
199
|
+
}
|
|
200
|
+
return hashes;
|
|
201
|
+
}
|
|
202
|
+
function chunkedRows(context, artifactIds, sql) {
|
|
203
|
+
const rows = [];
|
|
204
|
+
const uniqueIds = [...new Set(artifactIds)];
|
|
205
|
+
for (let index = 0; index < uniqueIds.length; index += READ_CHUNK) {
|
|
206
|
+
const chunk = uniqueIds.slice(index, index + READ_CHUNK);
|
|
207
|
+
if (chunk.length === 0)
|
|
208
|
+
continue;
|
|
209
|
+
const placeholders = chunk.map(() => "?").join(", ");
|
|
210
|
+
rows.push(...context.store.db
|
|
211
|
+
.prepare(sql(placeholders))
|
|
212
|
+
.all(...chunk));
|
|
213
|
+
}
|
|
214
|
+
return rows;
|
|
215
|
+
}
|
|
216
|
+
// --------------------------------------------------------------- writes
|
|
217
|
+
async function addManualTags(context, artifactReference, inputs) {
|
|
218
|
+
return resultOf(() => context.store.semanticOperation((commit) => {
|
|
219
|
+
const artifact = context.artifactRow(artifactReference);
|
|
220
|
+
const artifactId = artifact.artifact_id;
|
|
221
|
+
const tags = normalizeTagList(inputs);
|
|
222
|
+
if (tags.length === 0) {
|
|
223
|
+
throw new Error("At least one tag is required");
|
|
224
|
+
}
|
|
225
|
+
for (const tag of tags)
|
|
226
|
+
requireEntity(context, tag);
|
|
227
|
+
const existing = manualRowsByIdentity(context, artifactId);
|
|
228
|
+
const added = tags.filter((tag) => !existing.has(tagIdentity(tag.facet, tag.key)));
|
|
229
|
+
const total = existing.size + added.length;
|
|
230
|
+
if (total > MANUAL_TAGS_PER_ARTIFACT_MAX) {
|
|
231
|
+
throw new EngineFault({
|
|
232
|
+
code: "RESOURCE_EXHAUSTED",
|
|
233
|
+
message: `Artifact ${artifactId} would carry ${total} manual tags; the limit is ` +
|
|
234
|
+
`${MANUAL_TAGS_PER_ARTIFACT_MAX}`,
|
|
235
|
+
details: { artifactId, requested: total, limit: MANUAL_TAGS_PER_ARTIFACT_MAX },
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const dismissed = dismissedIdentities(context, artifactId);
|
|
239
|
+
const changed = tags.filter((tag) => {
|
|
240
|
+
const identity = tagIdentity(tag.facet, tag.key);
|
|
241
|
+
if (dismissed.has(identity))
|
|
242
|
+
return true;
|
|
243
|
+
const row = existing.get(identity);
|
|
244
|
+
if (!row)
|
|
245
|
+
return true;
|
|
246
|
+
return row.label !== tag.label || (row.entity_id ?? undefined) !== tag.entityId;
|
|
247
|
+
});
|
|
248
|
+
if (changed.length === 0)
|
|
249
|
+
return ok(tagState(context, artifactId));
|
|
250
|
+
const mutation = commit({
|
|
251
|
+
operation: "add_artifact_tags",
|
|
252
|
+
tables: ["artifact_tags", "artifact_tag_dismissals"],
|
|
253
|
+
artifactId,
|
|
254
|
+
details: { artifactId, tags: changed.map(identityDetail) },
|
|
255
|
+
writeSet: changed.map((tag) => writeSetKey(artifactId, tag)),
|
|
256
|
+
}, (_operationId, now) => {
|
|
257
|
+
const insert = context.store.db.prepare(`INSERT INTO artifact_tags(
|
|
258
|
+
artifact_id, origin, facet, tag_key, label, entity_id, created_at
|
|
259
|
+
) VALUES (?, 'manual', ?, ?, ?, ?, ?)
|
|
260
|
+
ON CONFLICT(artifact_id, origin, facet, tag_key) DO UPDATE SET
|
|
261
|
+
label=excluded.label,
|
|
262
|
+
entity_id=excluded.entity_id`);
|
|
263
|
+
const clearDismissal = context.store.db.prepare(`DELETE FROM artifact_tag_dismissals
|
|
264
|
+
WHERE artifact_id=? AND facet=? AND tag_key=?`);
|
|
265
|
+
for (const tag of changed) {
|
|
266
|
+
insert.run(artifactId, tag.facet, tag.key, tag.label, tag.entityId ?? null, now);
|
|
267
|
+
// An explicit add is explicit consent: it clears the durable
|
|
268
|
+
// suppression that a previous removal recorded.
|
|
269
|
+
clearDismissal.run(artifactId, tag.facet, tag.key);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
return ok(tagState(context, artifactId), mutation.revision);
|
|
273
|
+
}));
|
|
274
|
+
}
|
|
275
|
+
async function removeTag(context, artifactReference, input) {
|
|
276
|
+
return resultOf(() => context.store.semanticOperation((commit) => {
|
|
277
|
+
const artifact = context.artifactRow(artifactReference);
|
|
278
|
+
const artifactId = artifact.artifact_id;
|
|
279
|
+
const identity = normalizeTagIdentity(input);
|
|
280
|
+
const manual = manualRowsByIdentity(context, artifactId).get(tagIdentity(identity.facet, identity.key));
|
|
281
|
+
const dismissal = context.store.db
|
|
282
|
+
.prepare(`SELECT artifact_id, facet, tag_key, label, dismissed_at
|
|
283
|
+
FROM artifact_tag_dismissals
|
|
284
|
+
WHERE artifact_id=? AND facet=? AND tag_key=?`)
|
|
285
|
+
.get(artifactId, identity.facet, identity.key);
|
|
286
|
+
if (!manual && dismissal)
|
|
287
|
+
return ok(tagState(context, artifactId));
|
|
288
|
+
if (!dismissal)
|
|
289
|
+
assertDismissalCapacity(context, artifactId);
|
|
290
|
+
// The dismissal keeps the label the user actually saw, so a restored
|
|
291
|
+
// suppression reads the same way it did when it was removed.
|
|
292
|
+
const label = manual?.label ?? automaticLabel(context, artifactId, identity) ??
|
|
293
|
+
identity.label;
|
|
294
|
+
const mutation = commit({
|
|
295
|
+
operation: "remove_artifact_tag",
|
|
296
|
+
tables: ["artifact_tags", "artifact_tag_dismissals"],
|
|
297
|
+
artifactId,
|
|
298
|
+
details: {
|
|
299
|
+
artifactId,
|
|
300
|
+
facet: identity.facet,
|
|
301
|
+
key: identity.key,
|
|
302
|
+
},
|
|
303
|
+
writeSet: [writeSetKey(artifactId, identity)],
|
|
304
|
+
}, (_operationId, now) => {
|
|
305
|
+
context.store.db
|
|
306
|
+
.prepare(`DELETE FROM artifact_tags
|
|
307
|
+
WHERE artifact_id=? AND origin='manual' AND facet=? AND tag_key=?`)
|
|
308
|
+
.run(artifactId, identity.facet, identity.key);
|
|
309
|
+
context.store.db
|
|
310
|
+
.prepare(`INSERT INTO artifact_tag_dismissals(
|
|
311
|
+
artifact_id, facet, tag_key, label, dismissed_at
|
|
312
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
313
|
+
ON CONFLICT(artifact_id, facet, tag_key) DO UPDATE SET
|
|
314
|
+
label=excluded.label`)
|
|
315
|
+
.run(artifactId, identity.facet, identity.key, label, now);
|
|
316
|
+
});
|
|
317
|
+
return ok(tagState(context, artifactId), mutation.revision);
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
async function restoreTag(context, artifactReference, input) {
|
|
321
|
+
return resultOf(() => context.store.semanticOperation((commit) => {
|
|
322
|
+
const artifact = context.artifactRow(artifactReference);
|
|
323
|
+
const artifactId = artifact.artifact_id;
|
|
324
|
+
const identity = normalizeTagIdentity(input);
|
|
325
|
+
const present = context.store.db
|
|
326
|
+
.prepare(`SELECT 1 AS present FROM artifact_tag_dismissals
|
|
327
|
+
WHERE artifact_id=? AND facet=? AND tag_key=?`)
|
|
328
|
+
.get(artifactId, identity.facet, identity.key);
|
|
329
|
+
if (!present)
|
|
330
|
+
return ok(tagState(context, artifactId));
|
|
331
|
+
const mutation = commit({
|
|
332
|
+
operation: "restore_artifact_tag",
|
|
333
|
+
tables: ["artifact_tag_dismissals"],
|
|
334
|
+
artifactId,
|
|
335
|
+
details: { artifactId, facet: identity.facet, key: identity.key },
|
|
336
|
+
writeSet: [writeSetKey(artifactId, identity)],
|
|
337
|
+
}, () => {
|
|
338
|
+
context.store.db
|
|
339
|
+
.prepare(`DELETE FROM artifact_tag_dismissals
|
|
340
|
+
WHERE artifact_id=? AND facet=? AND tag_key=?`)
|
|
341
|
+
.run(artifactId, identity.facet, identity.key);
|
|
342
|
+
});
|
|
343
|
+
return ok(tagState(context, artifactId), mutation.revision);
|
|
344
|
+
}));
|
|
345
|
+
}
|
|
346
|
+
async function replaceAutomaticTags(context, input) {
|
|
347
|
+
return resultOf(() => context.store.semanticOperation((commit) => {
|
|
348
|
+
const artifact = context.artifactRow(input.artifactId);
|
|
349
|
+
const artifactId = artifact.artifact_id;
|
|
350
|
+
const { sourceHash, generator, extractorVersion, model, tags } = normalizeAutomaticTags(input);
|
|
351
|
+
if (input.expectedGeneration !== undefined &&
|
|
352
|
+
(!Number.isSafeInteger(input.expectedGeneration) || input.expectedGeneration < 0)) {
|
|
353
|
+
throw new Error("Automatic tag expectedGeneration must be a nonnegative integer");
|
|
354
|
+
}
|
|
355
|
+
for (const tag of tags)
|
|
356
|
+
requireEntity(context, tag);
|
|
357
|
+
const current = snapshotRow(context, artifactId);
|
|
358
|
+
const generation = current?.generation ?? 0;
|
|
359
|
+
if (input.expectedGeneration !== undefined &&
|
|
360
|
+
input.expectedGeneration !== generation) {
|
|
361
|
+
throw new EngineFault({
|
|
362
|
+
code: "STALE_REVISION",
|
|
363
|
+
message: `Automatic tags for ${artifactId} expected generation ` +
|
|
364
|
+
`${input.expectedGeneration} but the catalog is at ${generation}`,
|
|
365
|
+
details: {
|
|
366
|
+
artifactId,
|
|
367
|
+
expectedGeneration: input.expectedGeneration,
|
|
368
|
+
generation,
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
if (snapshotMatches(current, {
|
|
373
|
+
sourceHash,
|
|
374
|
+
generator,
|
|
375
|
+
...(model ? { model } : {}),
|
|
376
|
+
extractorVersion,
|
|
377
|
+
}) &&
|
|
378
|
+
automaticTagsMatch(context.store.db, artifactId, tags)) {
|
|
379
|
+
// Re-running the same analyzer over the same bytes with the same
|
|
380
|
+
// answer is not history; it mints no commit and does not advance
|
|
381
|
+
// the fence.
|
|
382
|
+
return ok(tagState(context, artifactId));
|
|
383
|
+
}
|
|
384
|
+
const mutation = commit({
|
|
385
|
+
operation: "replace_automatic_artifact_tags",
|
|
386
|
+
tables: ["artifact_tags", "artifact_tag_snapshots"],
|
|
387
|
+
artifactId,
|
|
388
|
+
details: {
|
|
389
|
+
artifactId,
|
|
390
|
+
sourceHash,
|
|
391
|
+
generator,
|
|
392
|
+
extractorVersion,
|
|
393
|
+
generation: generation + 1,
|
|
394
|
+
tags: tags.map(identityDetail),
|
|
395
|
+
},
|
|
396
|
+
writeSet: [`artifact-tags-automatic:${artifactId}`],
|
|
397
|
+
}, (_operationId, now) => {
|
|
398
|
+
context.store.db
|
|
399
|
+
.prepare("DELETE FROM artifact_tags WHERE artifact_id=? AND origin='automatic'")
|
|
400
|
+
.run(artifactId);
|
|
401
|
+
const insert = context.store.db.prepare(`INSERT INTO artifact_tags(
|
|
402
|
+
artifact_id, origin, facet, tag_key, label, entity_id, created_at
|
|
403
|
+
) VALUES (?, 'automatic', ?, ?, ?, ?, ?)`);
|
|
404
|
+
for (const tag of tags) {
|
|
405
|
+
insert.run(artifactId, tag.facet, tag.key, tag.label, tag.entityId ?? null, now);
|
|
406
|
+
}
|
|
407
|
+
context.store.db
|
|
408
|
+
.prepare(`INSERT INTO artifact_tag_snapshots(
|
|
409
|
+
artifact_id, source_hash, generator, model, extractor_version,
|
|
410
|
+
tag_count, generation, analyzed_at
|
|
411
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
412
|
+
ON CONFLICT(artifact_id) DO UPDATE SET
|
|
413
|
+
source_hash=excluded.source_hash,
|
|
414
|
+
generator=excluded.generator,
|
|
415
|
+
model=excluded.model,
|
|
416
|
+
extractor_version=excluded.extractor_version,
|
|
417
|
+
tag_count=excluded.tag_count,
|
|
418
|
+
generation=excluded.generation,
|
|
419
|
+
analyzed_at=excluded.analyzed_at`)
|
|
420
|
+
.run(artifactId, sourceHash, generator, model || null, extractorVersion, tags.length, generation + 1, now);
|
|
421
|
+
});
|
|
422
|
+
return ok(tagState(context, artifactId), mutation.revision);
|
|
423
|
+
}));
|
|
424
|
+
}
|
|
425
|
+
// --------------------------------------------------------------- helpers
|
|
426
|
+
function manualRowsByIdentity(context, artifactId) {
|
|
427
|
+
const rows = context.store.db
|
|
428
|
+
.prepare(`SELECT artifact_id, origin, facet, tag_key, label, entity_id, created_at
|
|
429
|
+
FROM artifact_tags
|
|
430
|
+
WHERE artifact_id=? AND origin='manual'`)
|
|
431
|
+
.all(artifactId);
|
|
432
|
+
return new Map(rows.map((row) => [tagIdentity(row.facet, row.tag_key), row]));
|
|
433
|
+
}
|
|
434
|
+
function dismissedIdentities(context, artifactId) {
|
|
435
|
+
const rows = context.store.db
|
|
436
|
+
.prepare("SELECT facet, tag_key FROM artifact_tag_dismissals WHERE artifact_id=?")
|
|
437
|
+
.all(artifactId);
|
|
438
|
+
return new Set(rows.map((row) => tagIdentity(row.facet, row.tag_key)));
|
|
439
|
+
}
|
|
440
|
+
function assertDismissalCapacity(context, artifactId) {
|
|
441
|
+
const row = context.store.db
|
|
442
|
+
.prepare("SELECT COUNT(*) AS total FROM artifact_tag_dismissals WHERE artifact_id=?")
|
|
443
|
+
.get(artifactId);
|
|
444
|
+
if (row.total >= TAG_DISMISSALS_PER_ARTIFACT_MAX) {
|
|
445
|
+
throw new EngineFault({
|
|
446
|
+
code: "RESOURCE_EXHAUSTED",
|
|
447
|
+
message: `Artifact ${artifactId} already carries ${row.total} dismissals; the limit is ` +
|
|
448
|
+
`${TAG_DISMISSALS_PER_ARTIFACT_MAX}`,
|
|
449
|
+
details: {
|
|
450
|
+
artifactId,
|
|
451
|
+
total: row.total,
|
|
452
|
+
limit: TAG_DISMISSALS_PER_ARTIFACT_MAX,
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function automaticLabel(context, artifactId, identity) {
|
|
458
|
+
const row = context.store.db
|
|
459
|
+
.prepare(`SELECT label FROM artifact_tags
|
|
460
|
+
WHERE artifact_id=? AND origin='automatic' AND facet=? AND tag_key=?`)
|
|
461
|
+
.get(artifactId, identity.facet, identity.key);
|
|
462
|
+
return row?.label;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Entity references are carried, never invented: a tag may point at an
|
|
466
|
+
* entity the caller has already confirmed, and the reference must resolve.
|
|
467
|
+
*/
|
|
468
|
+
function requireEntity(context, tag) {
|
|
469
|
+
if (!tag.entityId)
|
|
470
|
+
return;
|
|
471
|
+
const row = context.store.db
|
|
472
|
+
.prepare("SELECT 1 AS present FROM entities WHERE entity_id=?")
|
|
473
|
+
.get(tag.entityId);
|
|
474
|
+
if (!row) {
|
|
475
|
+
throw new EngineFault({
|
|
476
|
+
code: "NOT_FOUND",
|
|
477
|
+
message: `Tag entity does not exist: ${tag.entityId}`,
|
|
478
|
+
details: { entityId: tag.entityId },
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function identityDetail(tag) {
|
|
483
|
+
return tagIdentity(tag.facet, tag.key);
|
|
484
|
+
}
|
|
485
|
+
function writeSetKey(artifactId, tag) {
|
|
486
|
+
return `artifact-tag:${artifactId}:${tagIdentity(tag.facet, tag.key)}`;
|
|
487
|
+
}
|
|
488
|
+
//# sourceMappingURL=tags.js.map
|
package/dist/tags.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"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"}
|
package/docs/doltlite-staging.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
# DoltLite staging and native merge verification
|
|
2
2
|
|
|
3
|
-
The engine pins DoltLite 0.50.6.
|
|
3
|
+
The engine pins the temporary DoltLite `0.50.6-videobook.1` fork package from
|
|
4
|
+
[justintanner/doltlite](https://github.com/justintanner/doltlite/tree/videobook-node-package/packaging/videobook-node).
|
|
5
|
+
Its native source is `b3981dc9ed6b2e39c247b4d598b2691e19dd0b25`; its Node
|
|
6
|
+
wrapper is the published 0.50.6 wrapper at `4bed4889be31c683f81291e2f661d07e50b7a3fe`.
|
|
7
|
+
The dependency uses the [versioned release tarball](https://github.com/justintanner/doltlite/releases/tag/videobook-node-v0.50.6-videobook.1) and lockfile integrity.
|
|
8
|
+
Tarball SHA256: `4968a0be9b32aad3d2052b556a5b89c465f9a7959f053e0f12148a2f9d0faf3c`.
|
|
9
|
+
All 12 [package CI jobs](https://github.com/justintanner/doltlite/actions/runs/34049056350) passed, including clean installs on all five platforms and a source rebuild.
|
|
10
|
+
It includes the fix for
|
|
4
11
|
[dolthub/doltlite#2644](https://github.com/dolthub/doltlite/issues/2644),
|
|
5
12
|
merged in [PR 2646](https://github.com/dolthub/doltlite/pull/2646) and
|
|
6
13
|
published in [0.50.6](https://github.com/dolthub/doltlite/releases/tag/v0.50.6).
|
|
7
|
-
The
|
|
8
|
-
|
|
14
|
+
The original adoption is tracked in `ve-ovz.23`; fork packaging and installed
|
|
15
|
+
native-merge verification are tracked in `ve-wsu.6`.
|
|
9
16
|
|
|
10
17
|
## Fixed: incremental staging corrupts index roots
|
|
11
18
|
|
|
@@ -21,7 +28,7 @@ node scripts/dolt-staging-probe.cjs @dolthub/doltlite --stage-all
|
|
|
21
28
|
|
|
22
29
|
Full engine URL bootstrap, backed-up catalog cloning, lazy object reads,
|
|
23
30
|
post-clone writes and reopen are verified in `tests/fork-flow.test.ts`.
|
|
24
|
-
`tests/merge-policy.test.ts` verifies
|
|
31
|
+
`tests/merge-policy.test.ts` verifies full-catalog checkout and native merges preserve
|
|
25
32
|
all 56 engine tables, ignored runtime rows, indexed file lookups, and integrity.
|
|
26
33
|
The transcript and primary-sequence tests now perform both native merges
|
|
27
34
|
instead of inserting the second branch's expected rows directly. Native row
|
|
@@ -31,7 +38,7 @@ The upstream change prevents new corrupt commits; it does not rewrite
|
|
|
31
38
|
previously corrupted history. Snapshot bootstrap remains available for a
|
|
32
39
|
healthy working catalog whose old committed schema cannot be cloned.
|
|
33
40
|
|
|
34
|
-
##
|
|
41
|
+
## Fixed in the fork: ignored runtime tables block native merge
|
|
35
42
|
|
|
36
43
|
A separate failure reproduces on 0.50.6 with one versioned table and one
|
|
37
44
|
ignored runtime table. Native merge refuses with an uncommitted-changes error
|
|
@@ -45,19 +52,32 @@ node scripts/dolt-ignored-merge-probe.cjs @dolthub/doltlite --without-index
|
|
|
45
52
|
node scripts/dolt-ignored-merge-probe.cjs @dolthub/doltlite
|
|
46
53
|
```
|
|
47
54
|
|
|
48
|
-
The latter two commands
|
|
49
|
-
All probes use temporary synthetic catalogs and remove them
|
|
50
|
-
the package argument with an absolute installed-package
|
|
51
|
-
|
|
52
|
-
including singleton reconciliation and forget-wins
|
|
53
|
-
|
|
55
|
+
The latter two commands exit nonzero on unpatched 0.50.6. All three pass with
|
|
56
|
+
the pinned fork. All probes use temporary synthetic catalogs and remove them
|
|
57
|
+
on exit. Replace the package argument with an absolute installed-package
|
|
58
|
+
directory to test another build. The engine's merge-back flow keeps its
|
|
59
|
+
application policies, including singleton reconciliation and forget-wins
|
|
60
|
+
object handling.
|
|
54
61
|
|
|
55
62
|
A [native source patch with validation and reproduction steps](../patches/doltlite/README.md)
|
|
56
|
-
|
|
63
|
+
was prepared on upstream commit `37a390eb7b021962d9d287a465a2da3c9f59c3cf`.
|
|
57
64
|
It passes 4,156 focused checks including allocation failures, all 126 native
|
|
58
|
-
suites, all 33 C suites, and the full 56-table engine catalog probe.
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
suites, all 33 C suites, and the full 56-table engine catalog probe. It was
|
|
66
|
+
merged upstream in [PR 2664](https://github.com/dolthub/doltlite/pull/2664).
|
|
67
|
+
The temporary package provides prebuilt addons for Linux x64/arm64, macOS
|
|
68
|
+
x64/arm64, and Windows x64, plus matching source for the existing build fallback.
|
|
69
|
+
Its `fork-provenance.json` records source commits and binary checksums.
|
|
70
|
+
For npm versions that enforce `allowScripts`, the policy key is the exact
|
|
71
|
+
release asset URL; a registry-style name/version key does not match this
|
|
72
|
+
remote tarball dependency.
|
|
73
|
+
|
|
74
|
+
`npm run test:package` installs the engine in an empty project and checks the
|
|
75
|
+
actual installed fork with `scripts/native-full-catalog-merge-probe.mjs`.
|
|
76
|
+
That probe preserves 23 runtime tables, 107 schema objects, and deleted job ID
|
|
77
|
+
high-water marks through fast-forward, three-way, conflict rollback, and reopen.
|
|
78
|
+
Replace the fork with an upstream release once that installed artifact passes
|
|
79
|
+
the same checks; remove the fork-version assertion in the package smoke at that
|
|
80
|
+
time. No schema or file-format change is required for this adoption.
|
|
61
81
|
|
|
62
82
|
Compatibility smoke tests created separate synthetic catalogs with the previous
|
|
63
83
|
engine dependency (0.11.37) and the installed application dependency (0.11.51),
|
package/docs/edit-performance.md
CHANGED
|
@@ -62,8 +62,7 @@ Seeding the 1,000 clips took 142 ms to preview and 297 ms to commit. All 50
|
|
|
62
62
|
previews left the head revision, row counts and sequence projection unchanged,
|
|
63
63
|
all 50 repeats were identical, all 50 commits advanced the head and applied
|
|
64
64
|
5,000 transforms, and every gate passed. Process peak RSS was 2.8 GiB
|
|
65
|
-
including the embedded Dolt database.
|
|
66
|
-
with 16 GB RAM; this run does not replace a reference-device measurement.
|
|
65
|
+
including the embedded Dolt database.
|
|
67
66
|
|
|
68
67
|
## DoltLite 0.50.6 candidate
|
|
69
68
|
|
|
@@ -79,5 +78,4 @@ records 50 independent 100-operation transactions over 1,000 clips:
|
|
|
79
78
|
| Commit | 50 | 299 ms | 331 ms | 348 ms |
|
|
80
79
|
|
|
81
80
|
All mutation, determinism, revision, and applied-transform gates pass. Peak
|
|
82
|
-
process RSS is 1.54 GiB.
|
|
83
|
-
qualification; `ve-ovz.22` remains outstanding.
|
|
81
|
+
process RSS is 1.54 GiB.
|