@nestos/kanban 0.0.0-stage → 0.5.1
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 +121 -2
- package/dist/activity-C6xDM-cg.d.cts +232 -0
- package/dist/activity-Dw8DOw0L.d.ts +232 -0
- package/dist/activity.cjs +288 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +34 -0
- package/dist/activity.d.ts +34 -0
- package/dist/activity.js +288 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-2YFPV5GF.cjs +16 -0
- package/dist/chunk-2YFPV5GF.cjs.map +1 -0
- package/dist/chunk-4KF7KUAI.cjs +221 -0
- package/dist/chunk-4KF7KUAI.cjs.map +1 -0
- package/dist/chunk-4XF6LQSU.cjs +9 -0
- package/dist/chunk-4XF6LQSU.cjs.map +1 -0
- package/dist/chunk-5DLZWW5Y.js +148 -0
- package/dist/chunk-5DLZWW5Y.js.map +1 -0
- package/dist/chunk-5XKOCKY2.js +58 -0
- package/dist/chunk-5XKOCKY2.js.map +1 -0
- package/dist/chunk-6MN3H3YF.cjs +183 -0
- package/dist/chunk-6MN3H3YF.cjs.map +1 -0
- package/dist/chunk-ATUFFNLV.js +221 -0
- package/dist/chunk-ATUFFNLV.js.map +1 -0
- package/dist/chunk-DFTOTBGF.js +439 -0
- package/dist/chunk-DFTOTBGF.js.map +1 -0
- package/dist/chunk-G6FCDLDF.js +16 -0
- package/dist/chunk-G6FCDLDF.js.map +1 -0
- package/dist/chunk-IUI5CI2S.cjs +439 -0
- package/dist/chunk-IUI5CI2S.cjs.map +1 -0
- package/dist/chunk-KYNYPKKH.cjs +71 -0
- package/dist/chunk-KYNYPKKH.cjs.map +1 -0
- package/dist/chunk-L44TM4EE.cjs +1498 -0
- package/dist/chunk-L44TM4EE.cjs.map +1 -0
- package/dist/chunk-LSE6JG5I.cjs +20 -0
- package/dist/chunk-LSE6JG5I.cjs.map +1 -0
- package/dist/chunk-O4OGAAV4.js +71 -0
- package/dist/chunk-O4OGAAV4.js.map +1 -0
- package/dist/chunk-OHQTKGQN.js +1498 -0
- package/dist/chunk-OHQTKGQN.js.map +1 -0
- package/dist/chunk-PSKQAFDF.cjs +58 -0
- package/dist/chunk-PSKQAFDF.cjs.map +1 -0
- package/dist/chunk-QTMTBEBA.js +20 -0
- package/dist/chunk-QTMTBEBA.js.map +1 -0
- package/dist/chunk-RQP77ZTY.js +9 -0
- package/dist/chunk-RQP77ZTY.js.map +1 -0
- package/dist/chunk-T7P5EIC4.cjs +148 -0
- package/dist/chunk-T7P5EIC4.cjs.map +1 -0
- package/dist/chunk-TB2RZGDV.js +183 -0
- package/dist/chunk-TB2RZGDV.js.map +1 -0
- package/dist/content-CAIp1njn.d.cts +35 -0
- package/dist/content-CGMJdyH_.d.ts +35 -0
- package/dist/contracts/index.cjs +21 -0
- package/dist/contracts/index.cjs.map +1 -0
- package/dist/contracts/index.d.cts +4 -0
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.js +21 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/discovery-DxpirOz3.d.cts +61 -0
- package/dist/discovery-gSqWpuRm.d.ts +61 -0
- package/dist/discovery.cjs +379 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +22 -0
- package/dist/discovery.d.ts +22 -0
- package/dist/discovery.js +379 -0
- package/dist/discovery.js.map +1 -0
- package/dist/execution.cjs +368 -0
- package/dist/execution.cjs.map +1 -0
- package/dist/execution.d.cts +89 -0
- package/dist/execution.d.ts +89 -0
- package/dist/execution.js +368 -0
- package/dist/execution.js.map +1 -0
- package/dist/index.cjs +76 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +61 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/module-BbvwdCDF.d.cts +11 -0
- package/dist/module-CWNK2BMj.d.ts +11 -0
- package/dist/planning-CcFZYdIL.d.cts +844 -0
- package/dist/planning-CcFZYdIL.d.ts +844 -0
- package/dist/ports-Bn6ro2FB.d.ts +142 -0
- package/dist/ports-CaL6geqR.d.cts +142 -0
- package/dist/storage.cjs +289 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +71 -0
- package/dist/storage.d.ts +71 -0
- package/dist/storage.js +289 -0
- package/dist/storage.js.map +1 -0
- package/dist/store-Ct0gOAAg.d.ts +28 -0
- package/dist/store-q63eSMoT.d.cts +28 -0
- package/dist/ui/index.cjs +1961 -0
- package/dist/ui/index.cjs.map +1 -0
- package/dist/ui/index.d.cts +209 -0
- package/dist/ui/index.d.ts +209 -0
- package/dist/ui/index.js +1961 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/kanban.css +194 -0
- package/package.json +113 -4
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } async function _asyncOptionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
var _chunkL44TM4EEcjs = require('./chunk-L44TM4EE.cjs');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
var _chunk2YFPV5GFcjs = require('./chunk-2YFPV5GF.cjs');
|
|
24
|
+
|
|
25
|
+
// src/store.ts
|
|
26
|
+
var _vfscore = require('@nestos/vfs-core');
|
|
27
|
+
var SeqKanbanStore = class _SeqKanbanStore {
|
|
28
|
+
constructor(fs, path, bodies) {
|
|
29
|
+
this.fs = fs;
|
|
30
|
+
this.path = path;
|
|
31
|
+
this.bodies = _nullishCoalesce(bodies, () => ( { read: async (hash) => {
|
|
32
|
+
const body = await fs.meta.assets.getAsset(path, `${hash}.json`);
|
|
33
|
+
if (body === null || body instanceof ArrayBuffer) return body;
|
|
34
|
+
throw new (0, _chunk2YFPV5GFcjs.KanbanError)("BODY_INTEGRITY");
|
|
35
|
+
}, write: async (hash, bytes) => {
|
|
36
|
+
await fs.meta.assets.putAsset(path, `${hash}.json`, bytes);
|
|
37
|
+
} }));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static async open(fs, directory = "/kanban", bodies) {
|
|
41
|
+
if (!_optionalChain([fs, 'access', _2 => _2.meta, 'access', _3 => _3.seq, 'optionalAccess', _4 => _4.transaction])) throw new (0, _chunk2YFPV5GFcjs.KanbanError)("TRANSACTION_REQUIRED");
|
|
42
|
+
try {
|
|
43
|
+
await fs.driver.createFile({ parentPath: directory, name: "boards.seq", type: "seqfile", recursive: true });
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (!(error instanceof _vfscore.FSError) || error.code !== "EEXIST") throw error;
|
|
46
|
+
}
|
|
47
|
+
return new _SeqKanbanStore(fs, `${directory}/boards.seq`, bodies);
|
|
48
|
+
}
|
|
49
|
+
async boardId(number) {
|
|
50
|
+
return this.fs.meta.seq.getEntry(this.path, _chunkL44TM4EEcjs.boardNumberKey.call(void 0, number));
|
|
51
|
+
}
|
|
52
|
+
async ids() {
|
|
53
|
+
return JSON.parse(await _asyncNullishCoalesce(await this.fs.meta.seq.getEntry(this.path, "index"), async () => ( "[]")));
|
|
54
|
+
}
|
|
55
|
+
async events(id, after, limit, through) {
|
|
56
|
+
const end = Math.min(through, after + limit);
|
|
57
|
+
const keys = Array.from({ length: Math.max(0, end - after) }, (_, index) => `event/${encodeURIComponent(id)}/${String(after + index + 1).padStart(16, "0")}`);
|
|
58
|
+
if (!keys.length) return [];
|
|
59
|
+
const rows = await this.fs.meta.seq.getEntries(this.path, keys);
|
|
60
|
+
return keys.filter((key) => rows[key] !== void 0).map((key) => JSON.parse(rows[key]));
|
|
61
|
+
}
|
|
62
|
+
async archived(boardId, itemId) {
|
|
63
|
+
const raw = await this.fs.meta.seq.getEntry(this.path, _chunkL44TM4EEcjs.archiveKey.call(void 0, boardId, itemId));
|
|
64
|
+
if (!raw) return null;
|
|
65
|
+
const record = await _chunkL44TM4EEcjs.decodeRow.call(void 0, raw, this.bodies);
|
|
66
|
+
record.item.number ??= await _asyncOptionalChain([(await this.view(boardId)), 'optionalAccess', async _5 => _5.state, 'access', async _6 => _6.archiveIndex, 'optionalAccess', async _7 => _7.find, 'call', async _8 => _8((item) => item.id === itemId), 'optionalAccess', async _9 => _9.number]);
|
|
67
|
+
return record;
|
|
68
|
+
}
|
|
69
|
+
async load(id, receiptKey) {
|
|
70
|
+
return this.fs.meta.seq.transaction(async (tx) => {
|
|
71
|
+
const raw = await tx.getEntry(this.path, _chunkL44TM4EEcjs.boardKey.call(void 0, id));
|
|
72
|
+
return { raw, rows: await tx.getEntries(this.path, _chunkL44TM4EEcjs.rowKeys.call(void 0, raw)), receipt: receiptKey ? await tx.getEntry(this.path, receiptKey) : void 0 };
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async view(id) {
|
|
76
|
+
const raw = await this.fs.meta.seq.getEntry(this.path, _chunkL44TM4EEcjs.boardKey.call(void 0, id));
|
|
77
|
+
const indexed = _chunkL44TM4EEcjs.indexedView.call(void 0, raw);
|
|
78
|
+
if (indexed) return indexed;
|
|
79
|
+
const state = await this.read(id);
|
|
80
|
+
return state ? _chunkL44TM4EEcjs.viewFromState.call(void 0, state) : null;
|
|
81
|
+
}
|
|
82
|
+
async read(id) {
|
|
83
|
+
return _chunkL44TM4EEcjs.hydrate.call(void 0, await this.load(id), this.bodies);
|
|
84
|
+
}
|
|
85
|
+
async update(id, operationId, fingerprint, change) {
|
|
86
|
+
const receiptKey = `receipt/${encodeURIComponent(id)}/${encodeURIComponent(operationId)}`;
|
|
87
|
+
const before = await this.load(id, receiptKey), current = await _chunkL44TM4EEcjs.hydrate.call(void 0, before, this.bodies), receipt = before.receipt;
|
|
88
|
+
if (receipt) {
|
|
89
|
+
_chunkL44TM4EEcjs.verifyReceipt.call(void 0, receipt, fingerprint);
|
|
90
|
+
if (!current) throw new (0, _chunk2YFPV5GFcjs.KanbanError)("CORRUPT_RECEIPT");
|
|
91
|
+
return current;
|
|
92
|
+
}
|
|
93
|
+
const original = JSON.stringify(current), next = change(current);
|
|
94
|
+
_chunkL44TM4EEcjs.numberEntities.call(void 0, next);
|
|
95
|
+
if (JSON.stringify(next) === original) return next;
|
|
96
|
+
return this.persist(id, receiptKey, fingerprint, before, next);
|
|
97
|
+
}
|
|
98
|
+
async persist(id, receiptKey, fingerprint, before, next) {
|
|
99
|
+
const events = [...next.events], archives = await Promise.all((_nullishCoalesce(next.archiveWrites, () => ( []))).map(async (write) => ({ key: _chunkL44TM4EEcjs.archiveKey.call(void 0, id, write.id), value: write.value ? await _chunkL44TM4EEcjs.encodeRow.call(void 0, write.value, this.bodies) : null })));
|
|
100
|
+
delete next.archiveWrites;
|
|
101
|
+
next.events = [];
|
|
102
|
+
const encoded = await _chunkL44TM4EEcjs.encodeBoard.call(void 0, next, this.bodies);
|
|
103
|
+
const committed = await this.fs.meta.seq.transaction(async (tx) => {
|
|
104
|
+
const latestReceipt = await tx.getEntry(this.path, receiptKey);
|
|
105
|
+
if (latestReceipt) {
|
|
106
|
+
_chunkL44TM4EEcjs.verifyReceipt.call(void 0, latestReceipt, fingerprint);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
if (await tx.getEntry(this.path, _chunkL44TM4EEcjs.boardKey.call(void 0, id)) !== before.raw) throw new (0, _chunk2YFPV5GFcjs.KanbanError)("REVISION_CONFLICT");
|
|
110
|
+
await commitBoardNumber(tx, this.path, id, before, next, encoded);
|
|
111
|
+
const eventRows = events.map((event) => ({ key: `event/${encodeURIComponent(id)}/${String(event.sequence).padStart(16, "0")}`, value: JSON.stringify(event) }));
|
|
112
|
+
await writeRows(tx, this.path, [
|
|
113
|
+
...eventRows,
|
|
114
|
+
..._chunkL44TM4EEcjs.rowChanges.call(void 0, before, encoded),
|
|
115
|
+
...archives,
|
|
116
|
+
{ key: _chunkL44TM4EEcjs.boardKey.call(void 0, id), value: encoded.raw },
|
|
117
|
+
{ key: receiptKey, value: _chunkL44TM4EEcjs.receiptDigest.call(void 0, fingerprint) }
|
|
118
|
+
]);
|
|
119
|
+
const ids = JSON.parse(await _asyncNullishCoalesce(await tx.getEntry(this.path, "index"), async () => ( "[]")));
|
|
120
|
+
if (!ids.includes(id)) await tx.setEntry(this.path, "index", JSON.stringify([...ids, id]));
|
|
121
|
+
return next;
|
|
122
|
+
});
|
|
123
|
+
if (committed) return committed;
|
|
124
|
+
const replay = await this.read(id);
|
|
125
|
+
if (!replay) throw new (0, _chunk2YFPV5GFcjs.KanbanError)("CORRUPT_RECEIPT");
|
|
126
|
+
return replay;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
async function writeRows(tx, path, rows) {
|
|
130
|
+
for (const row of rows) {
|
|
131
|
+
if (row.value === null) await tx.deleteEntry(path, row.key);
|
|
132
|
+
else await tx.setEntry(path, row.key, row.value);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function commitBoardNumber(tx, path, id, before, next, encoded) {
|
|
136
|
+
const previous = _chunkL44TM4EEcjs.counter.call(void 0, await tx.getEntry(path, _chunkL44TM4EEcjs.boardCounterKey));
|
|
137
|
+
next.board.number = _chunkL44TM4EEcjs.allocateBoardNumber.call(void 0, before.raw, previous);
|
|
138
|
+
const owner = await tx.getEntry(path, _chunkL44TM4EEcjs.boardNumberKey.call(void 0, next.board.number));
|
|
139
|
+
if (owner !== null && owner !== id) throw new (0, _chunk2YFPV5GFcjs.KanbanError)("INVALID_NUMBERING");
|
|
140
|
+
encoded.raw = _chunkL44TM4EEcjs.patchBoardNumber.call(void 0, encoded.raw, next.board.number);
|
|
141
|
+
await tx.setEntry(path, _chunkL44TM4EEcjs.boardCounterKey, String(Math.max(previous, next.board.number)));
|
|
142
|
+
await tx.setEntry(path, _chunkL44TM4EEcjs.boardNumberKey.call(void 0, next.board.number), id);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
exports.SeqKanbanStore = SeqKanbanStore;
|
|
148
|
+
//# sourceMappingURL=chunk-T7P5EIC4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-T7P5EIC4.cjs","../src/store.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACtBA,2CAA0C;AAKnC,IAAM,eAAA,EAAN,MAAM,gBAAsC;AAAA,EAEvC,WAAA,CAA6B,EAAA,EAAkC,IAAA,EAAc,MAAA,EAA0B;AAA1E,IAAA,IAAA,CAAA,GAAA,EAAA,EAAA;AAAkC,IAAA,IAAA,CAAA,KAAA,EAAA,IAAA;AACnE,IAAA,IAAA,CAAK,OAAA,mBAAS,MAAA,UAAU,EAAC,IAAA,EAAM,MAAA,CAAM,IAAA,EAAA,GAAQ;AACzC,MAAA,MAAM,KAAA,EAAO,MAAM,EAAA,CAAG,IAAA,CAAK,MAAA,CAAO,QAAA,CAAS,IAAA,EAAM,CAAA,EAAA;AACC,MAAA;AACZ,MAAA;AACT,IAAA;AAA4C,MAAA;AAAiB,IAAA;AAClG,EAAA;AAPiB,EAAA;AAQ4F,EAAA;AAChE,IAAA;AACrC,IAAA;AAA2C,MAAA;AACjC,IAAA;AAAoD,MAAA;AAAuB,IAAA;AAC/C,IAAA;AAC9C,EAAA;AACsD,EAAA;AAA8C,IAAA;AAAwB,EAAA;AAC7F,EAAA;AACwB,IAAA;AACvD,EAAA;AACgG,EAAA;AACjD,IAAA;AACQ,IAAA;AAEzB,IAAA;AAE2B,IAAA;AACF,IAAA;AACvD,EAAA;AAEoF,EAAA;AAC9B,IAAA;AACjC,IAAA;AAAyE,IAAA;AACvC,IAAA;AAAqE,IAAA;AAC5H,EAAA;AACsG,EAAA;AAChD,IAAA;AACD,MAAA;AACD,MAAA;AAC/C,IAAA;AACL,EAAA;AACuB,EAAA;AAC+B,IAAA;AACnB,IAAA;AAAuB,IAAA;AACtB,IAAA;AAAyC,IAAA;AAC7E,EAAA;AACoD,EAAA;AAAgD,IAAA;AAAE,EAAA;AAExB,EAAA;AACtB,IAAA;AACJ,IAAA;AACnC,IAAA;AAAmC,MAAA;AAAuC,MAAA;AAA2B,MAAA;AAAQ,IAAA;AACzE,IAAA;AAC9B,IAAA;AAC2B,IAAA;AACG,IAAA;AACrD,EAAA;AACgG,EAAA;AAC1C,IAAA;AAEtC,IAAA;AAA8B,IAAA;AAES,IAAA;AACT,IAAA;AACO,MAAA;AAC1B,MAAA;AAAyC,QAAA;AAAU,QAAA;AAAK,MAAA;AACnC,MAAA;AACG,MAAA;AACE,MAAA;AACd,MAAA;AAAI,QAAA;AAAwC,QAAA;AAAM,QAAA;AAC3C,QAAA;AAA0C,QAAA;AAAc,MAAA;AACtC,MAAA;AACV,MAAA;AACvC,MAAA;AACV,IAAA;AACqB,IAAA;AACW,IAAA;AAAuD,IAAA;AAAU,IAAA;AACtG,EAAA;AACJ;AAC4J;AAChI,EAAA;AAC+B,IAAA;AACJ,IAAA;AACnD,EAAA;AACJ;AAEoI;AAC/E,EAAA;AACG,EAAA;AACC,EAAA;AACP,EAAA;AACI,EAAA;AACG,EAAA;AACH,EAAA;AACtD;AD2CwD;AACA;AACA;AACA","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-T7P5EIC4.cjs","sourcesContent":[null,"import {numberEntities, boardCounterKey, boardNumberKey, counter, allocateBoardNumber, patchBoardNumber} from './numbering';\nimport type { KanbanEvent, KanbanArchivedItem } from './contracts';\nimport { FSError, type IFileSystem } from '@nestos/vfs-core';\nimport { KanbanError, type KanbanState, type KanbanStore } from './ports';\nimport {indexedView, viewFromState, archiveKey, boardKey as key, rowKeys, hydrate, encodeBoard, rowChanges, encodeRow, decodeRow, receiptDigest, verifyReceipt, type StoredBoard, type KanbanBodyStore} from './storage-codec';\n\n/** One user-scoped journal, with atomic board/index/receipt commits. */\nexport class SeqKanbanStore implements KanbanStore {\n private readonly bodies: KanbanBodyStore;\n private constructor(private readonly fs: IFileSystem, private readonly path: string, bodies?: KanbanBodyStore) {\n this.bodies = bodies ?? {read: async hash => {\n const body = await fs.meta.assets.getAsset(path, `${hash}.json`);\n if (body === null || body instanceof ArrayBuffer) return body;\n throw new KanbanError('BODY_INTEGRITY');\n }, write: async (hash, bytes) => {await fs.meta.assets.putAsset(path, `${hash}.json`, bytes);}};\n }\n static async open(fs: IFileSystem, directory = '/kanban', bodies?: KanbanBodyStore): Promise<SeqKanbanStore> {\n if (!fs.meta.seq?.transaction) throw new KanbanError('TRANSACTION_REQUIRED');\n try { await fs.driver.createFile({ parentPath: directory, name: 'boards.seq', type: 'seqfile', recursive: true }); }\n catch (error) { if (!(error instanceof FSError) || error.code !== 'EEXIST') throw error; }\n return new SeqKanbanStore(fs, `${directory}/boards.seq`, bodies);\n }\n async boardId(number: number): Promise<string | null> {return this.fs.meta.seq!.getEntry(this.path, boardNumberKey(number));}\n async ids(): Promise<string[]> {\n return JSON.parse(await this.fs.meta.seq!.getEntry(this.path, 'index') ?? '[]');\n }\n async events(id: string, after: number, limit: number, through: number): Promise<KanbanEvent[]> {\n const end = Math.min(through, after + limit);\n const keys = Array.from({length: Math.max(0, end - after)}, (_, index) =>\n `event/${encodeURIComponent(id)}/${String(after + index + 1).padStart(16, '0')}`);\n if (!keys.length) return [];\n // The committed sequence freezes this immutable prefix; bulk key reads avoid history scans.\n const rows = await this.fs.meta.seq!.getEntries(this.path, keys);\n return keys.filter(key => rows[key] !== undefined).map(key => JSON.parse(rows[key]) as KanbanEvent);\n }\n\n async archived(boardId: string, itemId: string): Promise<KanbanArchivedItem | null> {\n const raw = await this.fs.meta.seq!.getEntry(this.path, archiveKey(boardId, itemId));\n if (!raw) return null; const record = await decodeRow<KanbanArchivedItem>(raw, this.bodies);\n record.item.number ??= (await this.view(boardId))?.state.archiveIndex?.find(item => item.id === itemId)?.number; return record;\n }\n private async load(id: string, receiptKey?: string): Promise<StoredBoard & {receipt?: string | null}> {\n return this.fs.meta.seq!.transaction!(async tx => {\n const raw = await tx.getEntry(this.path, key(id));\n return {raw, rows: await tx.getEntries(this.path, rowKeys(raw)), receipt: receiptKey ? await tx.getEntry(this.path, receiptKey) : undefined};\n });\n }\n async view(id: string) {\n const raw = await this.fs.meta.seq!.getEntry(this.path, key(id));\n const indexed = indexedView(raw); if (indexed) return indexed;\n const state = await this.read(id); return state ? viewFromState(state) : null;\n }\n async read(id: string): Promise<KanbanState | null> {return hydrate(await this.load(id), this.bodies);}\n async update(id: string, operationId: string, fingerprint: string,\n change: (state: KanbanState | null) => KanbanState): Promise<KanbanState> {\n const receiptKey = `receipt/${encodeURIComponent(id)}/${encodeURIComponent(operationId)}`;\n const before = await this.load(id, receiptKey), current = await hydrate(before, this.bodies), receipt = before.receipt;\n if (receipt) {verifyReceipt(receipt, fingerprint); if (!current) throw new KanbanError('CORRUPT_RECEIPT'); return current;}\n const original = JSON.stringify(current), next = change(current);\n numberEntities(next);\n if (JSON.stringify(next) === original) return next;\n return this.persist(id, receiptKey, fingerprint, before, next);\n }\n private async persist(id: string, receiptKey: string, fingerprint: string, before: StoredBoard, next: KanbanState): Promise<KanbanState> {\n const events = [...next.events], archives = await Promise.all((next.archiveWrites ?? []).map(async write =>\n ({key: archiveKey(id, write.id), value: write.value ? await encodeRow(write.value, this.bodies) : null})));\n delete next.archiveWrites; next.events = [];\n // No asset I/O runs under the SeqFile transaction: it may use the same backend.\n const encoded = await encodeBoard(next, this.bodies);\n const committed = await this.fs.meta.seq!.transaction!(async tx => {\n const latestReceipt = await tx.getEntry(this.path, receiptKey);\n if (latestReceipt) {verifyReceipt(latestReceipt, fingerprint); return null;}\n if (await tx.getEntry(this.path, key(id)) !== before.raw) throw new KanbanError('REVISION_CONFLICT');\n await commitBoardNumber(tx, this.path, id, before, next, encoded);\n const eventRows = events.map(event => ({key: `event/${encodeURIComponent(id)}/${String(event.sequence).padStart(16, '0')}`, value: JSON.stringify(event)}));\n await writeRows(tx, this.path, [...eventRows, ...rowChanges(before, encoded), ...archives,\n {key: key(id), value: encoded.raw!}, {key: receiptKey, value: receiptDigest(fingerprint)}]);\n const ids: string[] = JSON.parse(await tx.getEntry(this.path, 'index') ?? '[]');\n if (!ids.includes(id)) await tx.setEntry(this.path, 'index', JSON.stringify([...ids, id]));\n return next;\n });\n if (committed) return committed;\n const replay = await this.read(id); if (!replay) throw new KanbanError('CORRUPT_RECEIPT'); return replay;\n }\n}\nasync function writeRows(tx: import('@nestos/vfs-core').ISeqFileTransaction, path: string, rows: Array<{key: string; value: string | null}>): Promise<void> {\n for (const row of rows) {\n if (row.value === null) await tx.deleteEntry(path, row.key);\n else await tx.setEntry(path, row.key, row.value);\n }\n}\n\nasync function commitBoardNumber(tx: import('@nestos/vfs-core').ISeqFileTransaction, path: string, id: string, before: StoredBoard, next: KanbanState, encoded: StoredBoard): Promise<void> {\n const previous = counter(await tx.getEntry(path, boardCounterKey));\n next.board.number = allocateBoardNumber(before.raw, previous);\n const owner = await tx.getEntry(path, boardNumberKey(next.board.number));\n if (owner !== null && owner !== id) throw new KanbanError('INVALID_NUMBERING');\n encoded.raw = patchBoardNumber(encoded.raw!, next.board.number);\n await tx.setEntry(path, boardCounterKey, String(Math.max(previous, next.board.number)));\n await tx.setEntry(path, boardNumberKey(next.board.number), id);\n}\n"]}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// src/utils/random.ts
|
|
2
|
+
function randomUUID() {
|
|
3
|
+
const webCrypto = globalThis.crypto;
|
|
4
|
+
if (typeof webCrypto?.randomUUID === "function") {
|
|
5
|
+
try {
|
|
6
|
+
return webCrypto.randomUUID();
|
|
7
|
+
} catch {
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return formatV4(randomBytes(16));
|
|
11
|
+
}
|
|
12
|
+
function randomBytes(length) {
|
|
13
|
+
const bytes = new Uint8Array(length);
|
|
14
|
+
if (typeof globalThis.crypto?.getRandomValues === "function") {
|
|
15
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
16
|
+
return bytes;
|
|
17
|
+
}
|
|
18
|
+
for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
19
|
+
return bytes;
|
|
20
|
+
}
|
|
21
|
+
function formatV4(bytes) {
|
|
22
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
23
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
24
|
+
const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, "0"));
|
|
25
|
+
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/utils/digest.ts
|
|
29
|
+
var SHA256_K = new Uint32Array([
|
|
30
|
+
1116352408,
|
|
31
|
+
1899447441,
|
|
32
|
+
3049323471,
|
|
33
|
+
3921009573,
|
|
34
|
+
961987163,
|
|
35
|
+
1508970993,
|
|
36
|
+
2453635748,
|
|
37
|
+
2870763221,
|
|
38
|
+
3624381080,
|
|
39
|
+
310598401,
|
|
40
|
+
607225278,
|
|
41
|
+
1426881987,
|
|
42
|
+
1925078388,
|
|
43
|
+
2162078206,
|
|
44
|
+
2614888103,
|
|
45
|
+
3248222580,
|
|
46
|
+
3835390401,
|
|
47
|
+
4022224774,
|
|
48
|
+
264347078,
|
|
49
|
+
604807628,
|
|
50
|
+
770255983,
|
|
51
|
+
1249150122,
|
|
52
|
+
1555081692,
|
|
53
|
+
1996064986,
|
|
54
|
+
2554220882,
|
|
55
|
+
2821834349,
|
|
56
|
+
2952996808,
|
|
57
|
+
3210313671,
|
|
58
|
+
3336571891,
|
|
59
|
+
3584528711,
|
|
60
|
+
113926993,
|
|
61
|
+
338241895,
|
|
62
|
+
666307205,
|
|
63
|
+
773529912,
|
|
64
|
+
1294757372,
|
|
65
|
+
1396182291,
|
|
66
|
+
1695183700,
|
|
67
|
+
1986661051,
|
|
68
|
+
2177026350,
|
|
69
|
+
2456956037,
|
|
70
|
+
2730485921,
|
|
71
|
+
2820302411,
|
|
72
|
+
3259730800,
|
|
73
|
+
3345764771,
|
|
74
|
+
3516065817,
|
|
75
|
+
3600352804,
|
|
76
|
+
4094571909,
|
|
77
|
+
275423344,
|
|
78
|
+
430227734,
|
|
79
|
+
506948616,
|
|
80
|
+
659060556,
|
|
81
|
+
883997877,
|
|
82
|
+
958139571,
|
|
83
|
+
1322822218,
|
|
84
|
+
1537002063,
|
|
85
|
+
1747873779,
|
|
86
|
+
1955562222,
|
|
87
|
+
2024104815,
|
|
88
|
+
2227730452,
|
|
89
|
+
2361852424,
|
|
90
|
+
2428436474,
|
|
91
|
+
2756734187,
|
|
92
|
+
3204031479,
|
|
93
|
+
3329325298
|
|
94
|
+
]);
|
|
95
|
+
var SHA256_H = new Uint32Array([
|
|
96
|
+
1779033703,
|
|
97
|
+
3144134277,
|
|
98
|
+
1013904242,
|
|
99
|
+
2773480762,
|
|
100
|
+
1359893119,
|
|
101
|
+
2600822924,
|
|
102
|
+
528734635,
|
|
103
|
+
1541459225
|
|
104
|
+
]);
|
|
105
|
+
var rotateRight = (value, bits) => (value >>> bits | value << 32 - bits) >>> 0;
|
|
106
|
+
function toBytes(input) {
|
|
107
|
+
if (typeof input === "string") return new TextEncoder().encode(input);
|
|
108
|
+
if (input instanceof Uint8Array && input.buffer instanceof ArrayBuffer) {
|
|
109
|
+
return input;
|
|
110
|
+
}
|
|
111
|
+
if (ArrayBuffer.isView(input)) {
|
|
112
|
+
const source = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
113
|
+
const copy = new Uint8Array(input.byteLength);
|
|
114
|
+
copy.set(source);
|
|
115
|
+
return copy;
|
|
116
|
+
}
|
|
117
|
+
return new Uint8Array(input);
|
|
118
|
+
}
|
|
119
|
+
function toHex(bytes) {
|
|
120
|
+
return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
121
|
+
}
|
|
122
|
+
function paddedMessage(message) {
|
|
123
|
+
const padded = new Uint8Array((Math.floor((message.length + 8) / 64) + 1) * 64);
|
|
124
|
+
padded.set(message);
|
|
125
|
+
padded[message.length] = 128;
|
|
126
|
+
const view = new DataView(padded.buffer);
|
|
127
|
+
const bitLength = message.length * 8;
|
|
128
|
+
view.setUint32(padded.length - 8, Math.floor(bitLength / 4294967296));
|
|
129
|
+
view.setUint32(padded.length - 4, bitLength >>> 0);
|
|
130
|
+
return padded;
|
|
131
|
+
}
|
|
132
|
+
function blockSchedule(view, offset) {
|
|
133
|
+
const words = new Uint32Array(64);
|
|
134
|
+
for (let i = 0; i < 16; i++) words[i] = view.getUint32(offset + i * 4);
|
|
135
|
+
for (let i = 16; i < 64; i++) {
|
|
136
|
+
const s0 = rotateRight(words[i - 15], 7) ^ rotateRight(words[i - 15], 18) ^ words[i - 15] >>> 3;
|
|
137
|
+
const s1 = rotateRight(words[i - 2], 17) ^ rotateRight(words[i - 2], 19) ^ words[i - 2] >>> 10;
|
|
138
|
+
words[i] = words[i - 16] + s0 + words[i - 7] + s1 >>> 0;
|
|
139
|
+
}
|
|
140
|
+
return words;
|
|
141
|
+
}
|
|
142
|
+
function compressBlock(state, words) {
|
|
143
|
+
let [a, b, c, d, e, f, g, h] = state;
|
|
144
|
+
for (let i = 0; i < 64; i++) {
|
|
145
|
+
const sigma1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);
|
|
146
|
+
const choose = e & f ^ ~e & g;
|
|
147
|
+
const temp1 = h + sigma1 + choose + SHA256_K[i] + words[i] >>> 0;
|
|
148
|
+
const sigma0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);
|
|
149
|
+
const majority = a & b ^ a & c ^ b & c;
|
|
150
|
+
const temp2 = sigma0 + majority >>> 0;
|
|
151
|
+
h = g;
|
|
152
|
+
g = f;
|
|
153
|
+
f = e;
|
|
154
|
+
e = d + temp1 >>> 0;
|
|
155
|
+
d = c;
|
|
156
|
+
c = b;
|
|
157
|
+
b = a;
|
|
158
|
+
a = temp1 + temp2 >>> 0;
|
|
159
|
+
}
|
|
160
|
+
const next = [a, b, c, d, e, f, g, h];
|
|
161
|
+
for (let i = 0; i < 8; i++) state[i] = state[i] + next[i] >>> 0;
|
|
162
|
+
}
|
|
163
|
+
function sha256Bytes(input) {
|
|
164
|
+
const padded = paddedMessage(toBytes(input));
|
|
165
|
+
const view = new DataView(padded.buffer);
|
|
166
|
+
const state = SHA256_H.slice();
|
|
167
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
168
|
+
compressBlock(state, blockSchedule(view, offset));
|
|
169
|
+
}
|
|
170
|
+
const out = new Uint8Array(32);
|
|
171
|
+
const outView = new DataView(out.buffer);
|
|
172
|
+
for (let i = 0; i < 8; i++) outView.setUint32(i * 4, state[i]);
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
function sha256HexSync(input) {
|
|
176
|
+
return toHex(sha256Bytes(input));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export {
|
|
180
|
+
randomUUID,
|
|
181
|
+
sha256HexSync
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=chunk-TB2RZGDV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/random.ts","../src/utils/digest.ts"],"sourcesContent":["/**\n * @file common/utils/random.ts\n * @description UUID v4 that also works outside a secure context.\n *\n * `crypto.randomUUID()` is secure-context-only: it is undefined over plain-HTTP\n * LAN origins (e.g. http://192.168.x.x:3000) and in WebKitGTK, so calling it\n * directly throws \"crypto.randomUUID is not a function\". `crypto.getRandomValues()`\n * stays available everywhere, so it backs the fallback below.\n */\n\n/** UUID v4 — native WebCrypto when available, `getRandomValues` otherwise. */\nexport function randomUUID(): string {\n const webCrypto = globalThis.crypto;\n if (typeof webCrypto?.randomUUID === 'function') {\n try {\n return webCrypto.randomUUID();\n } catch {\n // Present but unusable (insecure context) — fall through.\n }\n }\n return formatV4(randomBytes(16));\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes);\n return bytes;\n }\n for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);\n return bytes;\n}\n\nfunction formatV4(bytes: Uint8Array): string {\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC 4122 variant\n const hex = [...bytes].map(byte => byte.toString(16).padStart(2, '0'));\n return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10).join('')}`;\n}\n","/**\n * @file common/utils/digest.ts\n * @description SHA-256 that does not require WebCrypto.\n *\n * `crypto.subtle` only exists in a secure context (HTTPS or localhost) and is\n * absent in WebKitGTK, so `crypto.subtle.digest(...)` throws \"Cannot read\n * properties of undefined (reading 'digest')\" when the app is opened over a LAN\n * HTTP origin (e.g. http://192.168.x.x:3000) or in the packaged Linux app. The\n * pure-JS fallback below computes the very same SHA-256, so digests stay stable\n * across environments.\n */\n\n/** Any input a caller may want hashed. */\nexport type DigestInput = string | ArrayBuffer | ArrayBufferView;\n\nconst SHA256_K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst SHA256_H = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\nconst rotateRight = (value: number, bits: number): number =>\n ((value >>> bits) | (value << (32 - bits))) >>> 0;\n\nfunction toBytes(input: DigestInput): Uint8Array<ArrayBuffer> {\n if (typeof input === 'string') return new TextEncoder().encode(input);\n if (input instanceof Uint8Array && input.buffer instanceof ArrayBuffer) {\n return input as Uint8Array<ArrayBuffer>;\n }\n if (ArrayBuffer.isView(input)) {\n // Copy so WebCrypto gets a plain ArrayBuffer (never a SharedArrayBuffer view).\n const source = new Uint8Array(input.buffer as ArrayBufferLike, input.byteOffset, input.byteLength);\n const copy = new Uint8Array(input.byteLength);\n copy.set(source);\n return copy;\n }\n return new Uint8Array(input);\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return [...bytes].map(byte => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction paddedMessage(message: Uint8Array): Uint8Array {\n const padded = new Uint8Array((Math.floor((message.length + 8) / 64) + 1) * 64);\n padded.set(message);\n padded[message.length] = 0x80;\n const view = new DataView(padded.buffer);\n const bitLength = message.length * 8;\n view.setUint32(padded.length - 8, Math.floor(bitLength / 0x1_0000_0000));\n view.setUint32(padded.length - 4, bitLength >>> 0);\n return padded;\n}\n\nfunction blockSchedule(view: DataView, offset: number): Uint32Array {\n const words = new Uint32Array(64);\n for (let i = 0; i < 16; i++) words[i] = view.getUint32(offset + i * 4);\n for (let i = 16; i < 64; i++) {\n const s0 = rotateRight(words[i - 15], 7) ^ rotateRight(words[i - 15], 18) ^ (words[i - 15] >>> 3);\n const s1 = rotateRight(words[i - 2], 17) ^ rotateRight(words[i - 2], 19) ^ (words[i - 2] >>> 10);\n words[i] = (words[i - 16] + s0 + words[i - 7] + s1) >>> 0;\n }\n return words;\n}\n\nfunction compressBlock(state: Uint32Array, words: Uint32Array): void {\n let [a, b, c, d, e, f, g, h] = state;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);\n const choose = (e & f) ^ (~e & g);\n const temp1 = (h + sigma1 + choose + SHA256_K[i] + words[i]) >>> 0;\n const sigma0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);\n const majority = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (sigma0 + majority) >>> 0;\n h = g; g = f; f = e; e = (d + temp1) >>> 0;\n d = c; c = b; b = a; a = (temp1 + temp2) >>> 0;\n }\n const next = [a, b, c, d, e, f, g, h];\n for (let i = 0; i < 8; i++) state[i] = (state[i] + next[i]) >>> 0;\n}\n\n/** Pure-JS SHA-256 usable where WebCrypto is unavailable. */\nexport function sha256Bytes(input: DigestInput): Uint8Array {\n const padded = paddedMessage(toBytes(input));\n const view = new DataView(padded.buffer);\n const state = SHA256_H.slice();\n for (let offset = 0; offset < padded.length; offset += 64) {\n compressBlock(state, blockSchedule(view, offset));\n }\n const out = new Uint8Array(32);\n const outView = new DataView(out.buffer);\n for (let i = 0; i < 8; i++) outView.setUint32(i * 4, state[i]);\n return out;\n}\n\n/** SHA-256 hex digest — WebCrypto when available, pure JS otherwise. */\nexport async function sha256Hex(input: DigestInput): Promise<string> {\n const bytes = toBytes(input);\n const subtle = globalThis.crypto?.subtle;\n if (subtle?.digest) {\n try {\n return toHex(new Uint8Array(await subtle.digest('SHA-256', bytes)));\n } catch {\n // WebCrypto present but unusable (e.g. blocked by an insecure context).\n }\n }\n return toHex(sha256Bytes(bytes));\n}\n\n/** Synchronous SHA-256 hex digest (pure JS, no WebCrypto). */\nexport function sha256HexSync(input: DigestInput): string {\n return toHex(sha256Bytes(input));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { l as KanbanBoardInput, o as KanbanCommand, N as KanbanRecordInput, a2 as KanbanText, K as KanbanActor } from './planning-CcFZYdIL.cjs';
|
|
2
|
+
|
|
3
|
+
interface KanbanContentItem {
|
|
4
|
+
introduced?: number;
|
|
5
|
+
command: Extract<KanbanCommand, {
|
|
6
|
+
type: 'create-item';
|
|
7
|
+
}>;
|
|
8
|
+
blocked?: string;
|
|
9
|
+
completion?: {
|
|
10
|
+
resultRef: string;
|
|
11
|
+
archiveReason?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface KanbanContentRecord {
|
|
15
|
+
introduced?: number;
|
|
16
|
+
record: KanbanRecordInput;
|
|
17
|
+
confirmed?: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface KanbanContentAmendment extends KanbanText {
|
|
20
|
+
introduced?: number;
|
|
21
|
+
itemId: string;
|
|
22
|
+
runId: string;
|
|
23
|
+
proposedBy: KanbanActor;
|
|
24
|
+
}
|
|
25
|
+
/** Versioned host-provided content; contains no product presets or execution grants. */
|
|
26
|
+
interface KanbanContent {
|
|
27
|
+
id: string;
|
|
28
|
+
version: number;
|
|
29
|
+
board: KanbanBoardInput;
|
|
30
|
+
items: KanbanContentItem[];
|
|
31
|
+
records?: KanbanContentRecord[];
|
|
32
|
+
amendments?: KanbanContentAmendment[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type { KanbanContent as K, KanbanContentAmendment as a, KanbanContentItem as b, KanbanContentRecord as c };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { l as KanbanBoardInput, o as KanbanCommand, N as KanbanRecordInput, a2 as KanbanText, K as KanbanActor } from './planning-CcFZYdIL.js';
|
|
2
|
+
|
|
3
|
+
interface KanbanContentItem {
|
|
4
|
+
introduced?: number;
|
|
5
|
+
command: Extract<KanbanCommand, {
|
|
6
|
+
type: 'create-item';
|
|
7
|
+
}>;
|
|
8
|
+
blocked?: string;
|
|
9
|
+
completion?: {
|
|
10
|
+
resultRef: string;
|
|
11
|
+
archiveReason?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface KanbanContentRecord {
|
|
15
|
+
introduced?: number;
|
|
16
|
+
record: KanbanRecordInput;
|
|
17
|
+
confirmed?: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface KanbanContentAmendment extends KanbanText {
|
|
20
|
+
introduced?: number;
|
|
21
|
+
itemId: string;
|
|
22
|
+
runId: string;
|
|
23
|
+
proposedBy: KanbanActor;
|
|
24
|
+
}
|
|
25
|
+
/** Versioned host-provided content; contains no product presets or execution grants. */
|
|
26
|
+
interface KanbanContent {
|
|
27
|
+
id: string;
|
|
28
|
+
version: number;
|
|
29
|
+
board: KanbanBoardInput;
|
|
30
|
+
items: KanbanContentItem[];
|
|
31
|
+
records?: KanbanContentRecord[];
|
|
32
|
+
amendments?: KanbanContentAmendment[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type { KanbanContent as K, KanbanContentAmendment as a, KanbanContentItem as b, KanbanContentRecord as c };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkPSKQAFDFcjs = require('../chunk-PSKQAFDF.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var _chunkLSE6JG5Icjs = require('../chunk-LSE6JG5I.cjs');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
exports.DEFAULT_KANBAN_SCAN_POLICY = _chunkPSKQAFDFcjs.DEFAULT_KANBAN_SCAN_POLICY; exports.DEFAULT_KANBAN_WORK_TYPES = _chunkPSKQAFDFcjs.DEFAULT_KANBAN_WORK_TYPES; exports.boardAllowsStart = _chunkLSE6JG5Icjs.boardAllowsStart; exports.boardControlPhase = _chunkLSE6JG5Icjs.boardControlPhase; exports.executableWorkItem = _chunkPSKQAFDFcjs.executableWorkItem; exports.kanbanReference = _chunkPSKQAFDFcjs.kanbanReference; exports.sameAutomationBinding = _chunkPSKQAFDFcjs.sameAutomationBinding;
|
|
21
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/contracts/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF,4eAAC","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/contracts/index.cjs"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { D as DEFAULT_KANBAN_WORK_TYPES, K as KanbanActor, a as KanbanAmendment, b as KanbanAnalysisStatus, c as KanbanArchivedItem, d as KanbanArtifactRef, e as KanbanAssignment, f as KanbanAutomationCatalog, g as KanbanAutomationOption, h as KanbanAutomationSettings, i as KanbanAutomationTarget, j as KanbanBoard, k as KanbanBoardControl, l as KanbanBoardInput, m as KanbanBoardSummary, n as KanbanColumn, o as KanbanCommand, p as KanbanDiscoveryBatch, q as KanbanDiscoveryChange, r as KanbanDispatch, s as KanbanEstimate, t as KanbanEvent, u as KanbanExternalReference, v as KanbanFixSession, w as KanbanItem, x as KanbanItemPage, y as KanbanItemQuery, z as KanbanItemSummary, A as KanbanLaunch, B as KanbanMember, C as KanbanNotificationPolicy, E as KanbanOverview, F as KanbanParticipant, G as KanbanPlanning, H as KanbanPolicy, I as KanbanPrincipal, J as KanbanProjectRecord, L as KanbanPublishedPlan, M as KanbanRecordActivity, N as KanbanRecordInput, O as KanbanRecordPage, P as KanbanRecordQuery, Q as KanbanRecordSummary, R as KanbanReferenceTarget, S as KanbanRequest, T as KanbanService, U as KanbanSourceRef, V as KanbanSuggestion, W as KanbanSuggestionKind, X as KanbanSuggestionPage, Y as KanbanSuggestionQuery, Z as KanbanTaskCommand, _ as KanbanTaskControl, $ as KanbanTaskIssue, a0 as KanbanTaskPhase, a1 as KanbanTaskProjection, a2 as KanbanText, a3 as KanbanWorkDefinition, a4 as KanbanWorkPlan, a5 as KanbanWorkType, a6 as KanbanWorkflowCommand, a7 as KanbanWorkflowState, a8 as boardAllowsStart, a9 as boardControlPhase, aa as executableWorkItem, ab as kanbanReference, ac as sameAutomationBinding } from '../planning-CcFZYdIL.cjs';
|
|
2
|
+
export { D as DEFAULT_KANBAN_SCAN_POLICY, K as KanbanDiscoveryResult, a as KanbanScanConnection, b as KanbanScanInput, c as KanbanScanPolicy, d as KanbanScanSession, e as KanbanScanText } from '../discovery-DxpirOz3.cjs';
|
|
3
|
+
export { K as KanbanClient, a as KanbanDeletionPreview, b as KanbanDeletionRequest, c as KanbanExecutionSession, d as KanbanExecutionSessionDetail, e as KanbanItemOperation, f as KanbanItemOperationBinding, g as KanbanItemOperationRequest, h as KanbanItemOperations, i as KanbanItemResourceCatalog, j as KanbanOperationChoice, k as KanbanOperationField, l as KanbanRecordExecution, m as KanbanRecordResource, n as KanbanRecordRunRequest, o as KanbanRelatedSession, p as KanbanSessionActivityQuery, q as KanbanSessionAssociation, r as KanbanSessionDetailQuery, s as KanbanSessionExecution, t as KanbanSessionItemPage, u as KanbanSessionItemSummary, v as KanbanSessionPhase, w as KanbanSessionPurpose, x as KanbanWorkResource, y as KanbanWorkResourceCleanup, z as KanbanWorkResourceQuery } from '../activity-C6xDM-cg.cjs';
|
|
4
|
+
export { K as KanbanContent, a as KanbanContentAmendment, b as KanbanContentItem, c as KanbanContentRecord } from '../content-CAIp1njn.cjs';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { D as DEFAULT_KANBAN_WORK_TYPES, K as KanbanActor, a as KanbanAmendment, b as KanbanAnalysisStatus, c as KanbanArchivedItem, d as KanbanArtifactRef, e as KanbanAssignment, f as KanbanAutomationCatalog, g as KanbanAutomationOption, h as KanbanAutomationSettings, i as KanbanAutomationTarget, j as KanbanBoard, k as KanbanBoardControl, l as KanbanBoardInput, m as KanbanBoardSummary, n as KanbanColumn, o as KanbanCommand, p as KanbanDiscoveryBatch, q as KanbanDiscoveryChange, r as KanbanDispatch, s as KanbanEstimate, t as KanbanEvent, u as KanbanExternalReference, v as KanbanFixSession, w as KanbanItem, x as KanbanItemPage, y as KanbanItemQuery, z as KanbanItemSummary, A as KanbanLaunch, B as KanbanMember, C as KanbanNotificationPolicy, E as KanbanOverview, F as KanbanParticipant, G as KanbanPlanning, H as KanbanPolicy, I as KanbanPrincipal, J as KanbanProjectRecord, L as KanbanPublishedPlan, M as KanbanRecordActivity, N as KanbanRecordInput, O as KanbanRecordPage, P as KanbanRecordQuery, Q as KanbanRecordSummary, R as KanbanReferenceTarget, S as KanbanRequest, T as KanbanService, U as KanbanSourceRef, V as KanbanSuggestion, W as KanbanSuggestionKind, X as KanbanSuggestionPage, Y as KanbanSuggestionQuery, Z as KanbanTaskCommand, _ as KanbanTaskControl, $ as KanbanTaskIssue, a0 as KanbanTaskPhase, a1 as KanbanTaskProjection, a2 as KanbanText, a3 as KanbanWorkDefinition, a4 as KanbanWorkPlan, a5 as KanbanWorkType, a6 as KanbanWorkflowCommand, a7 as KanbanWorkflowState, a8 as boardAllowsStart, a9 as boardControlPhase, aa as executableWorkItem, ab as kanbanReference, ac as sameAutomationBinding } from '../planning-CcFZYdIL.js';
|
|
2
|
+
export { D as DEFAULT_KANBAN_SCAN_POLICY, K as KanbanDiscoveryResult, a as KanbanScanConnection, b as KanbanScanInput, c as KanbanScanPolicy, d as KanbanScanSession, e as KanbanScanText } from '../discovery-gSqWpuRm.js';
|
|
3
|
+
export { K as KanbanClient, a as KanbanDeletionPreview, b as KanbanDeletionRequest, c as KanbanExecutionSession, d as KanbanExecutionSessionDetail, e as KanbanItemOperation, f as KanbanItemOperationBinding, g as KanbanItemOperationRequest, h as KanbanItemOperations, i as KanbanItemResourceCatalog, j as KanbanOperationChoice, k as KanbanOperationField, l as KanbanRecordExecution, m as KanbanRecordResource, n as KanbanRecordRunRequest, o as KanbanRelatedSession, p as KanbanSessionActivityQuery, q as KanbanSessionAssociation, r as KanbanSessionDetailQuery, s as KanbanSessionExecution, t as KanbanSessionItemPage, u as KanbanSessionItemSummary, v as KanbanSessionPhase, w as KanbanSessionPurpose, x as KanbanWorkResource, y as KanbanWorkResourceCleanup, z as KanbanWorkResourceQuery } from '../activity-Dw8DOw0L.js';
|
|
4
|
+
export { K as KanbanContent, a as KanbanContentAmendment, b as KanbanContentItem, c as KanbanContentRecord } from '../content-CGMJdyH_.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_KANBAN_SCAN_POLICY,
|
|
3
|
+
DEFAULT_KANBAN_WORK_TYPES,
|
|
4
|
+
executableWorkItem,
|
|
5
|
+
kanbanReference,
|
|
6
|
+
sameAutomationBinding
|
|
7
|
+
} from "../chunk-5XKOCKY2.js";
|
|
8
|
+
import {
|
|
9
|
+
boardAllowsStart,
|
|
10
|
+
boardControlPhase
|
|
11
|
+
} from "../chunk-QTMTBEBA.js";
|
|
12
|
+
export {
|
|
13
|
+
DEFAULT_KANBAN_SCAN_POLICY,
|
|
14
|
+
DEFAULT_KANBAN_WORK_TYPES,
|
|
15
|
+
boardAllowsStart,
|
|
16
|
+
boardControlPhase,
|
|
17
|
+
executableWorkItem,
|
|
18
|
+
kanbanReference,
|
|
19
|
+
sameAutomationBinding
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { J as KanbanProjectRecord, z as KanbanItemSummary, j as KanbanBoard, q as KanbanDiscoveryChange, N as KanbanRecordInput } from './planning-CcFZYdIL.cjs';
|
|
2
|
+
|
|
3
|
+
interface KanbanScanSession {
|
|
4
|
+
id: string;
|
|
5
|
+
revision: string;
|
|
6
|
+
updatedAt: number | null;
|
|
7
|
+
idleSince: number | null;
|
|
8
|
+
activity: 'idle' | 'active' | 'waiting' | 'unknown';
|
|
9
|
+
archived: boolean;
|
|
10
|
+
scannerOwned?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface KanbanScanText {
|
|
13
|
+
session: KanbanScanSession;
|
|
14
|
+
complete: boolean;
|
|
15
|
+
messages: Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
role: 'user' | 'assistant';
|
|
18
|
+
text: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
interface KanbanScanConnection {
|
|
22
|
+
kind: 'local' | 'remote';
|
|
23
|
+
connectionId: string;
|
|
24
|
+
/** Explicit consent for moving source text to a different execution boundary. */
|
|
25
|
+
allowContentTransfer: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface KanbanScanPolicy {
|
|
28
|
+
idleMs: number;
|
|
29
|
+
includeArchived: boolean;
|
|
30
|
+
maxSessions: number;
|
|
31
|
+
maxInputBytes: number;
|
|
32
|
+
leaseMs: number;
|
|
33
|
+
autoCreate: boolean;
|
|
34
|
+
connection: KanbanScanConnection;
|
|
35
|
+
}
|
|
36
|
+
interface KanbanScanInput {
|
|
37
|
+
projectContext?: {
|
|
38
|
+
totalRecords: number;
|
|
39
|
+
excludedRecords?: number;
|
|
40
|
+
omittedRecords: number;
|
|
41
|
+
records: KanbanProjectRecord[];
|
|
42
|
+
};
|
|
43
|
+
context?: {
|
|
44
|
+
totalItems: number;
|
|
45
|
+
omittedItems: number;
|
|
46
|
+
archivedTotal: number;
|
|
47
|
+
archivedItems: KanbanItemSummary[];
|
|
48
|
+
};
|
|
49
|
+
runId: string;
|
|
50
|
+
executorId: string;
|
|
51
|
+
board: KanbanBoard;
|
|
52
|
+
sessions: KanbanScanText[];
|
|
53
|
+
connection: KanbanScanConnection;
|
|
54
|
+
}
|
|
55
|
+
declare const DEFAULT_KANBAN_SCAN_POLICY: Omit<KanbanScanPolicy, 'connection'>;
|
|
56
|
+
interface KanbanDiscoveryResult {
|
|
57
|
+
changes: KanbanDiscoveryChange[];
|
|
58
|
+
records?: KanbanRecordInput[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { DEFAULT_KANBAN_SCAN_POLICY as D, type KanbanDiscoveryResult as K, type KanbanScanConnection as a, type KanbanScanInput as b, type KanbanScanPolicy as c, type KanbanScanSession as d, type KanbanScanText as e };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { J as KanbanProjectRecord, z as KanbanItemSummary, j as KanbanBoard, q as KanbanDiscoveryChange, N as KanbanRecordInput } from './planning-CcFZYdIL.js';
|
|
2
|
+
|
|
3
|
+
interface KanbanScanSession {
|
|
4
|
+
id: string;
|
|
5
|
+
revision: string;
|
|
6
|
+
updatedAt: number | null;
|
|
7
|
+
idleSince: number | null;
|
|
8
|
+
activity: 'idle' | 'active' | 'waiting' | 'unknown';
|
|
9
|
+
archived: boolean;
|
|
10
|
+
scannerOwned?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface KanbanScanText {
|
|
13
|
+
session: KanbanScanSession;
|
|
14
|
+
complete: boolean;
|
|
15
|
+
messages: Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
role: 'user' | 'assistant';
|
|
18
|
+
text: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
interface KanbanScanConnection {
|
|
22
|
+
kind: 'local' | 'remote';
|
|
23
|
+
connectionId: string;
|
|
24
|
+
/** Explicit consent for moving source text to a different execution boundary. */
|
|
25
|
+
allowContentTransfer: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface KanbanScanPolicy {
|
|
28
|
+
idleMs: number;
|
|
29
|
+
includeArchived: boolean;
|
|
30
|
+
maxSessions: number;
|
|
31
|
+
maxInputBytes: number;
|
|
32
|
+
leaseMs: number;
|
|
33
|
+
autoCreate: boolean;
|
|
34
|
+
connection: KanbanScanConnection;
|
|
35
|
+
}
|
|
36
|
+
interface KanbanScanInput {
|
|
37
|
+
projectContext?: {
|
|
38
|
+
totalRecords: number;
|
|
39
|
+
excludedRecords?: number;
|
|
40
|
+
omittedRecords: number;
|
|
41
|
+
records: KanbanProjectRecord[];
|
|
42
|
+
};
|
|
43
|
+
context?: {
|
|
44
|
+
totalItems: number;
|
|
45
|
+
omittedItems: number;
|
|
46
|
+
archivedTotal: number;
|
|
47
|
+
archivedItems: KanbanItemSummary[];
|
|
48
|
+
};
|
|
49
|
+
runId: string;
|
|
50
|
+
executorId: string;
|
|
51
|
+
board: KanbanBoard;
|
|
52
|
+
sessions: KanbanScanText[];
|
|
53
|
+
connection: KanbanScanConnection;
|
|
54
|
+
}
|
|
55
|
+
declare const DEFAULT_KANBAN_SCAN_POLICY: Omit<KanbanScanPolicy, 'connection'>;
|
|
56
|
+
interface KanbanDiscoveryResult {
|
|
57
|
+
changes: KanbanDiscoveryChange[];
|
|
58
|
+
records?: KanbanRecordInput[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { DEFAULT_KANBAN_SCAN_POLICY as D, type KanbanDiscoveryResult as K, type KanbanScanConnection as a, type KanbanScanInput as b, type KanbanScanPolicy as c, type KanbanScanSession as d, type KanbanScanText as e };
|