@joewinke/jatui 0.36.3 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifact-blocks/AttachmentChip.svelte +66 -0
- package/dist/artifact-blocks/AttachmentChip.svelte.d.ts +7 -0
- package/dist/artifact-blocks/BlockComments.svelte +309 -0
- package/dist/artifact-blocks/BlockComments.svelte.d.ts +33 -0
- package/dist/artifact-blocks/BlockRenderer.svelte +674 -0
- package/dist/artifact-blocks/BlockRenderer.svelte.d.ts +55 -0
- package/dist/artifact-blocks/BlockVerdict.svelte +151 -0
- package/dist/artifact-blocks/BlockVerdict.svelte.d.ts +13 -0
- package/dist/artifact-blocks/BlocksArtifactView.svelte +1616 -0
- package/dist/artifact-blocks/BlocksArtifactView.svelte.d.ts +113 -0
- package/dist/artifact-blocks/CONTRACT.md +225 -0
- package/dist/artifact-blocks/CommentPill.svelte +49 -0
- package/dist/artifact-blocks/CommentPill.svelte.d.ts +16 -0
- package/dist/artifact-blocks/FoldedRounds.svelte +95 -0
- package/dist/artifact-blocks/FoldedRounds.svelte.d.ts +9 -0
- package/dist/artifact-blocks/Glyph.svelte +54 -0
- package/dist/artifact-blocks/Glyph.svelte.d.ts +10 -0
- package/dist/artifact-blocks/HistoryScrubber.svelte +500 -0
- package/dist/artifact-blocks/HistoryScrubber.svelte.d.ts +15 -0
- package/dist/artifact-blocks/Markdown.svelte +186 -0
- package/dist/artifact-blocks/Markdown.svelte.d.ts +30 -0
- package/dist/artifact-blocks/NoteComposer.svelte +31 -0
- package/dist/artifact-blocks/NoteComposer.svelte.d.ts +8 -0
- package/dist/artifact-blocks/PlainComposer.svelte +200 -0
- package/dist/artifact-blocks/PlainComposer.svelte.d.ts +15 -0
- package/dist/artifact-blocks/SectionTools.svelte +102 -0
- package/dist/artifact-blocks/SectionTools.svelte.d.ts +19 -0
- package/dist/artifact-blocks/adapter.d.ts +13 -0
- package/dist/artifact-blocks/adapter.js +31 -0
- package/dist/artifact-blocks/autoSend.d.ts +49 -0
- package/dist/artifact-blocks/autoSend.js +103 -0
- package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte +557 -0
- package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte.d.ts +48 -0
- package/dist/artifact-blocks/blocks/actions/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/actions/block.js +74 -0
- package/dist/artifact-blocks/blocks/actions/requests.d.ts +62 -0
- package/dist/artifact-blocks/blocks/actions/requests.js +26 -0
- package/dist/artifact-blocks/blocks/actions/schema.d.ts +168 -0
- package/dist/artifact-blocks/blocks/actions/schema.js +253 -0
- package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte +779 -0
- package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte.d.ts +40 -0
- package/dist/artifact-blocks/blocks/callout/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/callout/block.js +39 -0
- package/dist/artifact-blocks/blocks/callout/schema.d.ts +72 -0
- package/dist/artifact-blocks/blocks/callout/schema.js +115 -0
- package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte +875 -0
- package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte.d.ts +59 -0
- package/dist/artifact-blocks/blocks/chart/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/chart/block.js +70 -0
- package/dist/artifact-blocks/blocks/chart/schema.d.ts +171 -0
- package/dist/artifact-blocks/blocks/chart/schema.js +498 -0
- package/dist/artifact-blocks/blocks/chart/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/chart/thumb.js +201 -0
- package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte +1048 -0
- package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte.d.ts +16 -0
- package/dist/artifact-blocks/blocks/checklist/Icon.svelte +105 -0
- package/dist/artifact-blocks/blocks/checklist/Icon.svelte.d.ts +17 -0
- package/dist/artifact-blocks/blocks/checklist/block.d.ts +10 -0
- package/dist/artifact-blocks/blocks/checklist/block.js +63 -0
- package/dist/artifact-blocks/blocks/checklist/itemReview.d.ts +16 -0
- package/dist/artifact-blocks/blocks/checklist/itemReview.js +63 -0
- package/dist/artifact-blocks/blocks/checklist/labels.d.ts +62 -0
- package/dist/artifact-blocks/blocks/checklist/labels.js +96 -0
- package/dist/artifact-blocks/blocks/checklist/retest.d.ts +43 -0
- package/dist/artifact-blocks/blocks/checklist/retest.js +68 -0
- package/dist/artifact-blocks/blocks/checklist/schema.d.ts +84 -0
- package/dist/artifact-blocks/blocks/checklist/schema.js +91 -0
- package/dist/artifact-blocks/blocks/code/CodeBlock.svelte +128 -0
- package/dist/artifact-blocks/blocks/code/CodeBlock.svelte.d.ts +12 -0
- package/dist/artifact-blocks/blocks/code/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/code/block.js +31 -0
- package/dist/artifact-blocks/blocks/code/highlight.d.ts +34 -0
- package/dist/artifact-blocks/blocks/code/highlight.js +280 -0
- package/dist/artifact-blocks/blocks/code/schema.d.ts +32 -0
- package/dist/artifact-blocks/blocks/code/schema.js +39 -0
- package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte +290 -0
- package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte.d.ts +29 -0
- package/dist/artifact-blocks/blocks/collage/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/collage/block.js +29 -0
- package/dist/artifact-blocks/blocks/collage/schema.d.ts +52 -0
- package/dist/artifact-blocks/blocks/collage/schema.js +86 -0
- package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte +484 -0
- package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte.d.ts +25 -0
- package/dist/artifact-blocks/blocks/compare/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/compare/block.js +32 -0
- package/dist/artifact-blocks/blocks/compare/schema.d.ts +74 -0
- package/dist/artifact-blocks/blocks/compare/schema.js +148 -0
- package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte +392 -0
- package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte.d.ts +30 -0
- package/dist/artifact-blocks/blocks/diagram/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/diagram/block.js +50 -0
- package/dist/artifact-blocks/blocks/diagram/constants.d.ts +48 -0
- package/dist/artifact-blocks/blocks/diagram/constants.js +53 -0
- package/dist/artifact-blocks/blocks/diagram/schema.d.ts +161 -0
- package/dist/artifact-blocks/blocks/diagram/schema.js +621 -0
- package/dist/artifact-blocks/blocks/diagram/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/diagram/thumb.js +157 -0
- package/dist/artifact-blocks/blocks/diagram/types.d.ts +74 -0
- package/dist/artifact-blocks/blocks/diagram/types.js +1 -0
- package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte +81 -0
- package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte.d.ts +10 -0
- package/dist/artifact-blocks/blocks/diff/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/diff/block.js +36 -0
- package/dist/artifact-blocks/blocks/diff/schema.d.ts +18 -0
- package/dist/artifact-blocks/blocks/diff/schema.js +35 -0
- package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte +1055 -0
- package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/diff-review/block.d.ts +15 -0
- package/dist/artifact-blocks/blocks/diff-review/block.js +64 -0
- package/dist/artifact-blocks/blocks/diff-review/decisions.d.ts +57 -0
- package/dist/artifact-blocks/blocks/diff-review/decisions.js +80 -0
- package/dist/artifact-blocks/blocks/diff-review/schema.d.ts +13 -0
- package/dist/artifact-blocks/blocks/diff-review/schema.js +84 -0
- package/dist/artifact-blocks/blocks/diff-review/types.d.ts +35 -0
- package/dist/artifact-blocks/blocks/diff-review/types.js +1 -0
- package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte +145 -0
- package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/explainer/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/explainer/block.js +21 -0
- package/dist/artifact-blocks/blocks/explainer/schema.d.ts +26 -0
- package/dist/artifact-blocks/blocks/explainer/schema.js +69 -0
- package/dist/artifact-blocks/blocks/group-content.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-content.js +16 -0
- package/dist/artifact-blocks/blocks/group-data.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-data.js +7 -0
- package/dist/artifact-blocks/blocks/group-review.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-review.js +12 -0
- package/dist/artifact-blocks/blocks/group-visual.d.ts +17 -0
- package/dist/artifact-blocks/blocks/group-visual.js +14 -0
- package/dist/artifact-blocks/blocks/map/MapBlock.svelte +413 -0
- package/dist/artifact-blocks/blocks/map/MapBlock.svelte.d.ts +53 -0
- package/dist/artifact-blocks/blocks/map/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/map/block.js +62 -0
- package/dist/artifact-blocks/blocks/map/schema.d.ts +123 -0
- package/dist/artifact-blocks/blocks/map/schema.js +113 -0
- package/dist/artifact-blocks/blocks/map/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/map/thumb.js +69 -0
- package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte +33 -0
- package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte.d.ts +15 -0
- package/dist/artifact-blocks/blocks/markdown/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/markdown/block.js +28 -0
- package/dist/artifact-blocks/blocks/markdown/render.d.ts +17 -0
- package/dist/artifact-blocks/blocks/markdown/render.js +115 -0
- package/dist/artifact-blocks/blocks/markdown/schema.d.ts +10 -0
- package/dist/artifact-blocks/blocks/markdown/schema.js +23 -0
- package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte +2112 -0
- package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/media-picker/block.d.ts +24 -0
- package/dist/artifact-blocks/blocks/media-picker/block.js +137 -0
- package/dist/artifact-blocks/blocks/media-picker/choices.d.ts +28 -0
- package/dist/artifact-blocks/blocks/media-picker/choices.js +35 -0
- package/dist/artifact-blocks/blocks/media-picker/decisions.d.ts +51 -0
- package/dist/artifact-blocks/blocks/media-picker/decisions.js +75 -0
- package/dist/artifact-blocks/blocks/media-picker/schema.d.ts +7 -0
- package/dist/artifact-blocks/blocks/media-picker/schema.js +199 -0
- package/dist/artifact-blocks/blocks/media-picker/types.d.ts +92 -0
- package/dist/artifact-blocks/blocks/media-picker/types.js +1 -0
- package/dist/artifact-blocks/blocks/media-picker/versions.d.ts +51 -0
- package/dist/artifact-blocks/blocks/media-picker/versions.js +118 -0
- package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte +213 -0
- package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/mockup/block.d.ts +26 -0
- package/dist/artifact-blocks/blocks/mockup/block.js +52 -0
- package/dist/artifact-blocks/blocks/mockup/doc.d.ts +24 -0
- package/dist/artifact-blocks/blocks/mockup/doc.js +44 -0
- package/dist/artifact-blocks/blocks/mockup/sandbox.d.ts +21 -0
- package/dist/artifact-blocks/blocks/mockup/sandbox.js +27 -0
- package/dist/artifact-blocks/blocks/mockup/schema.d.ts +7 -0
- package/dist/artifact-blocks/blocks/mockup/schema.js +90 -0
- package/dist/artifact-blocks/blocks/mockup/types.d.ts +36 -0
- package/dist/artifact-blocks/blocks/mockup/types.js +17 -0
- package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte +359 -0
- package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte.d.ts +32 -0
- package/dist/artifact-blocks/blocks/program/block.d.ts +35 -0
- package/dist/artifact-blocks/blocks/program/block.js +68 -0
- package/dist/artifact-blocks/blocks/program/schema.d.ts +132 -0
- package/dist/artifact-blocks/blocks/program/schema.js +268 -0
- package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte +315 -0
- package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte.d.ts +24 -0
- package/dist/artifact-blocks/blocks/stats/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/stats/block.js +49 -0
- package/dist/artifact-blocks/blocks/stats/schema.d.ts +82 -0
- package/dist/artifact-blocks/blocks/stats/schema.js +43 -0
- package/dist/artifact-blocks/blocks/stats/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/stats/thumb.js +102 -0
- package/dist/artifact-blocks/blocks/table/TableBlock.svelte +490 -0
- package/dist/artifact-blocks/blocks/table/TableBlock.svelte.d.ts +28 -0
- package/dist/artifact-blocks/blocks/table/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/table/block.js +100 -0
- package/dist/artifact-blocks/blocks/table/schema.d.ts +143 -0
- package/dist/artifact-blocks/blocks/table/schema.js +278 -0
- package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte +347 -0
- package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte.d.ts +42 -0
- package/dist/artifact-blocks/blocks/timeline/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/timeline/block.js +96 -0
- package/dist/artifact-blocks/blocks/timeline/constants.d.ts +26 -0
- package/dist/artifact-blocks/blocks/timeline/constants.js +27 -0
- package/dist/artifact-blocks/blocks/timeline/schema.d.ts +102 -0
- package/dist/artifact-blocks/blocks/timeline/schema.js +405 -0
- package/dist/artifact-blocks/blocks/timeline/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/timeline/thumb.js +117 -0
- package/dist/artifact-blocks/blocks/timeline/types.d.ts +66 -0
- package/dist/artifact-blocks/blocks/timeline/types.js +1 -0
- package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte +169 -0
- package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte.d.ts +26 -0
- package/dist/artifact-blocks/blocks/transcript/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/transcript/block.js +86 -0
- package/dist/artifact-blocks/blocks/transcript/schema.d.ts +114 -0
- package/dist/artifact-blocks/blocks/transcript/schema.js +126 -0
- package/dist/artifact-blocks/builtins.d.ts +40 -0
- package/dist/artifact-blocks/builtins.js +22 -0
- package/dist/artifact-blocks/contractBlocks.d.ts +92 -0
- package/dist/artifact-blocks/contractBlocks.js +279 -0
- package/dist/artifact-blocks/history.d.ts +140 -0
- package/dist/artifact-blocks/history.js +363 -0
- package/dist/artifact-blocks/index.d.ts +40 -0
- package/dist/artifact-blocks/index.js +46 -0
- package/dist/artifact-blocks/listen/context.d.ts +30 -0
- package/dist/artifact-blocks/listen/context.js +30 -0
- package/dist/artifact-blocks/liveData.d.ts +78 -0
- package/dist/artifact-blocks/liveData.js +137 -0
- package/dist/artifact-blocks/liveDataPoller.d.ts +41 -0
- package/dist/artifact-blocks/liveDataPoller.js +140 -0
- package/dist/artifact-blocks/openNav.d.ts +46 -0
- package/dist/artifact-blocks/openNav.js +106 -0
- package/dist/artifact-blocks/pageReviewKeys.d.ts +17 -0
- package/dist/artifact-blocks/pageReviewKeys.js +115 -0
- package/dist/artifact-blocks/params.d.ts +98 -0
- package/dist/artifact-blocks/params.js +159 -0
- package/dist/artifact-blocks/registry.d.ts +27 -0
- package/dist/artifact-blocks/registry.js +83 -0
- package/dist/artifact-blocks/review/BlockIcon.svelte +99 -0
- package/dist/artifact-blocks/review/BlockIcon.svelte.d.ts +17 -0
- package/dist/artifact-blocks/review/BulkRejectForm.svelte +94 -0
- package/dist/artifact-blocks/review/BulkRejectForm.svelte.d.ts +11 -0
- package/dist/artifact-blocks/review/BulkUndoBar.svelte +40 -0
- package/dist/artifact-blocks/review/BulkUndoBar.svelte.d.ts +9 -0
- package/dist/artifact-blocks/review/ItemNote.svelte +193 -0
- package/dist/artifact-blocks/review/ItemNote.svelte.d.ts +33 -0
- package/dist/artifact-blocks/review/NoteToggle.svelte +52 -0
- package/dist/artifact-blocks/review/NoteToggle.svelte.d.ts +12 -0
- package/dist/artifact-blocks/review/TeamChip.svelte +71 -0
- package/dist/artifact-blocks/review/TeamChip.svelte.d.ts +8 -0
- package/dist/artifact-blocks/review/attachments.d.ts +10 -0
- package/dist/artifact-blocks/review/attachments.js +37 -0
- package/dist/artifact-blocks/review/bulk.d.ts +52 -0
- package/dist/artifact-blocks/review/bulk.js +61 -0
- package/dist/artifact-blocks/review/itemReview.d.ts +33 -0
- package/dist/artifact-blocks/review/itemReview.js +112 -0
- package/dist/artifact-blocks/review/roundLines.d.ts +14 -0
- package/dist/artifact-blocks/review/roundLines.js +20 -0
- package/dist/artifact-blocks/review/rounds.d.ts +86 -0
- package/dist/artifact-blocks/review/rounds.js +302 -0
- package/dist/artifact-blocks/review/saver.d.ts +23 -0
- package/dist/artifact-blocks/review/saver.js +48 -0
- package/dist/artifact-blocks/review/team.d.ts +31 -0
- package/dist/artifact-blocks/review/team.js +42 -0
- package/dist/artifact-blocks/review/visualOrder.d.ts +29 -0
- package/dist/artifact-blocks/review/visualOrder.js +66 -0
- package/dist/artifact-blocks/review.d.ts +180 -0
- package/dist/artifact-blocks/review.js +716 -0
- package/dist/artifact-blocks/thumb-kit.d.ts +80 -0
- package/dist/artifact-blocks/thumb-kit.js +149 -0
- package/dist/artifact-blocks/types.d.ts +513 -0
- package/dist/artifact-blocks/types.js +1 -0
- package/dist/components/Button.svelte +8 -0
- package/dist/components/TextInput.svelte +39 -6
- package/dist/components/TextInput.svelte.d.ts +15 -7
- package/dist/components/basic/Checkbox.svelte +52 -14
- package/dist/components/basic/Checkbox.svelte.d.ts +11 -1
- package/package.json +11 -2
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* History scrubber model (mos-p9m3g, living artifacts phase 4).
|
|
3
|
+
*
|
|
4
|
+
* "What did this page look like yesterday at 9am?" A blocks page has two
|
|
5
|
+
* clocks, and the state at any instant is one reading of each:
|
|
6
|
+
*
|
|
7
|
+
* LAYOUT the artifact_versions row live at that instant (the highest
|
|
8
|
+
* version created at or before it);
|
|
9
|
+
* DATA the artifact_data_history snapshot live at that instant (the
|
|
10
|
+
* newest recorded at or before it — migration 20272490000210
|
|
11
|
+
* captures every change of artifacts.data by trigger).
|
|
12
|
+
*
|
|
13
|
+
* This module is PURE (no db, no fetch): the history route resolves an
|
|
14
|
+
* instant with it on the server, and HistoryScrubber builds its timeline and
|
|
15
|
+
* diffs with it in the browser.
|
|
16
|
+
*
|
|
17
|
+
* Diffs are SHAPE-AWARE but never shape-dependent: a stats-shaped value
|
|
18
|
+
* (`cards[]` with label + numeric value) diffs as KPI deltas, a table-shaped
|
|
19
|
+
* value (`rows[]`) diffs as added / removed / changed rows, and anything
|
|
20
|
+
* else diffs as its changed numeric and text leaves. Data is untrusted: every
|
|
21
|
+
* reader here tolerates any JSON and caps what it reports.
|
|
22
|
+
*/
|
|
23
|
+
/** Mirrors the trigger's prune rule in drizzle/20272490000210 — keep both in
|
|
24
|
+
* step. The scrubber names where the trail ends with these. */
|
|
25
|
+
export const HISTORY_RETENTION = {
|
|
26
|
+
maxSnapshots: 500,
|
|
27
|
+
maxAgeDays: 30,
|
|
28
|
+
maxBytes: 32 * 1024 * 1024,
|
|
29
|
+
};
|
|
30
|
+
function toMs(iso) {
|
|
31
|
+
const ms = Date.parse(iso);
|
|
32
|
+
return Number.isFinite(ms) ? ms : NaN;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Merge versions and snapshots into one chronological list (oldest first).
|
|
36
|
+
* Entries with an unparseable timestamp are dropped — a point the scrubber
|
|
37
|
+
* cannot place is a point it cannot honestly show. At equal instants a
|
|
38
|
+
* version sorts before a data change (a republish then a data push in the
|
|
39
|
+
* same second reads in that order).
|
|
40
|
+
*/
|
|
41
|
+
export function buildTimeline(versions, snapshots) {
|
|
42
|
+
const points = [];
|
|
43
|
+
for (const v of versions) {
|
|
44
|
+
const ms = toMs(v.createdAt);
|
|
45
|
+
if (Number.isFinite(ms))
|
|
46
|
+
points.push({ kind: "version", at: v.createdAt, ms, version: v.version });
|
|
47
|
+
}
|
|
48
|
+
for (const s of snapshots) {
|
|
49
|
+
const ms = toMs(s.at);
|
|
50
|
+
if (Number.isFinite(ms))
|
|
51
|
+
points.push({ kind: "data", at: s.at, ms, snapshotId: s.id });
|
|
52
|
+
}
|
|
53
|
+
return points.sort((a, b) => a.ms - b.ms ||
|
|
54
|
+
(a.kind === b.kind ? 0 : a.kind === "version" ? -1 : 1) ||
|
|
55
|
+
(a.version ?? 0) - (b.version ?? 0));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The page state live at `atMs`: the newest version created at or before it
|
|
59
|
+
* and the newest snapshot recorded at or before it. Before the first
|
|
60
|
+
* snapshot, snapshotId is null — the page showed its inline params (or the
|
|
61
|
+
* trail was pruned; the caller says which via `trailStart`).
|
|
62
|
+
*/
|
|
63
|
+
export function stateAt(versions, snapshots, atMs) {
|
|
64
|
+
let version = null;
|
|
65
|
+
let versionMs = -Infinity;
|
|
66
|
+
for (const v of versions) {
|
|
67
|
+
const ms = toMs(v.createdAt);
|
|
68
|
+
if (!(ms <= atMs))
|
|
69
|
+
continue;
|
|
70
|
+
if (ms > versionMs || (ms === versionMs && v.version > (version ?? 0))) {
|
|
71
|
+
version = v.version;
|
|
72
|
+
versionMs = ms;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
let snap = null;
|
|
76
|
+
let snapMs = -Infinity;
|
|
77
|
+
// Snapshots arrive newest-first from the route; equal instants keep the
|
|
78
|
+
// first seen (the newest by seq).
|
|
79
|
+
for (const s of snapshots) {
|
|
80
|
+
const ms = toMs(s.at);
|
|
81
|
+
if (!(ms <= atMs))
|
|
82
|
+
continue;
|
|
83
|
+
if (ms > snapMs) {
|
|
84
|
+
snap = s;
|
|
85
|
+
snapMs = ms;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
version,
|
|
90
|
+
snapshotId: snap?.id ?? null,
|
|
91
|
+
dataAt: snap?.at ?? null,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** The oldest instant the trail can answer for, or null with no snapshots. */
|
|
95
|
+
export function trailStart(snapshots) {
|
|
96
|
+
let best = null;
|
|
97
|
+
let bestMs = Infinity;
|
|
98
|
+
for (const s of snapshots) {
|
|
99
|
+
const ms = toMs(s.at);
|
|
100
|
+
if (ms < bestMs) {
|
|
101
|
+
best = s.at;
|
|
102
|
+
bestMs = ms;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return best;
|
|
106
|
+
}
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Diffs
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
/** Most entries any one diff list reports — the rest are counted, not listed. */
|
|
111
|
+
const MAX_DIFF_ENTRIES = 50;
|
|
112
|
+
function isRecord(v) {
|
|
113
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
114
|
+
}
|
|
115
|
+
function own(obj, k) {
|
|
116
|
+
return Object.prototype.hasOwnProperty.call(obj, k) ? obj[k] : undefined;
|
|
117
|
+
}
|
|
118
|
+
/** Order-insensitive structural equality over plain JSON. */
|
|
119
|
+
function jsonEqual(a, b) {
|
|
120
|
+
if (a === b)
|
|
121
|
+
return true;
|
|
122
|
+
if (typeof a !== typeof b || a === null || b === null)
|
|
123
|
+
return false;
|
|
124
|
+
if (Array.isArray(a)) {
|
|
125
|
+
if (!Array.isArray(b) || a.length !== b.length)
|
|
126
|
+
return false;
|
|
127
|
+
return a.every((el, i) => jsonEqual(el, b[i]));
|
|
128
|
+
}
|
|
129
|
+
if (isRecord(a) && isRecord(b)) {
|
|
130
|
+
const ka = Object.keys(a);
|
|
131
|
+
const kb = Object.keys(b);
|
|
132
|
+
if (ka.length !== kb.length)
|
|
133
|
+
return false;
|
|
134
|
+
return ka.every((k) => own(b, k) !== undefined && jsonEqual(a[k], b[k]));
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
function finite(v) {
|
|
139
|
+
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
140
|
+
}
|
|
141
|
+
function kpiCards(v) {
|
|
142
|
+
if (!isRecord(v))
|
|
143
|
+
return null;
|
|
144
|
+
const cards = own(v, "cards");
|
|
145
|
+
if (!Array.isArray(cards))
|
|
146
|
+
return null;
|
|
147
|
+
const out = new Map();
|
|
148
|
+
for (const c of cards) {
|
|
149
|
+
if (!isRecord(c))
|
|
150
|
+
return null;
|
|
151
|
+
const label = own(c, "label");
|
|
152
|
+
if (typeof label !== "string" || !label)
|
|
153
|
+
return null;
|
|
154
|
+
if (!out.has(label))
|
|
155
|
+
out.set(label, finite(own(c, "value")));
|
|
156
|
+
}
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
function diffKpis(then, now) {
|
|
160
|
+
const labels = [...now.keys(), ...[...then.keys()].filter((l) => !now.has(l))];
|
|
161
|
+
return labels.slice(0, MAX_DIFF_ENTRIES).map((label) => {
|
|
162
|
+
const t = then.has(label) ? (then.get(label) ?? null) : null;
|
|
163
|
+
const n = now.has(label) ? (now.get(label) ?? null) : null;
|
|
164
|
+
const delta = t !== null && n !== null ? n - t : null;
|
|
165
|
+
const pct = delta !== null && t !== null && t !== 0 ? delta / Math.abs(t) : null;
|
|
166
|
+
return { label, then: t, now: n, delta, pct };
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/** Preferred identity columns for a table row, in order. */
|
|
170
|
+
const ROW_KEY_CANDIDATES = ["id", "key", "slug", "name", "label", "title"];
|
|
171
|
+
function tableRows(v) {
|
|
172
|
+
if (!isRecord(v))
|
|
173
|
+
return null;
|
|
174
|
+
const rows = own(v, "rows");
|
|
175
|
+
if (!Array.isArray(rows) || !rows.every(isRecord))
|
|
176
|
+
return null;
|
|
177
|
+
const cols = own(v, "columns");
|
|
178
|
+
const columns = Array.isArray(cols)
|
|
179
|
+
? cols
|
|
180
|
+
.map((c) => (isRecord(c) ? own(c, "key") : undefined))
|
|
181
|
+
.filter((k) => typeof k === "string")
|
|
182
|
+
: [];
|
|
183
|
+
return { rows: rows, columns };
|
|
184
|
+
}
|
|
185
|
+
/** The column that identifies a row across both sides: the first candidate
|
|
186
|
+
* (then the first declared column) whose values are present and unique on
|
|
187
|
+
* BOTH sides. Null → rows are matched by position. */
|
|
188
|
+
function rowKeyColumn(a, b, columns) {
|
|
189
|
+
const unique = (rows, col) => {
|
|
190
|
+
const seen = new Set();
|
|
191
|
+
for (const r of rows) {
|
|
192
|
+
const v = own(r, col);
|
|
193
|
+
if (typeof v !== "string" && typeof v !== "number")
|
|
194
|
+
return false;
|
|
195
|
+
const s = String(v);
|
|
196
|
+
if (seen.has(s))
|
|
197
|
+
return false;
|
|
198
|
+
seen.add(s);
|
|
199
|
+
}
|
|
200
|
+
return true;
|
|
201
|
+
};
|
|
202
|
+
for (const col of [...ROW_KEY_CANDIDATES, ...columns.slice(0, 1)]) {
|
|
203
|
+
if (unique(a, col) && unique(b, col))
|
|
204
|
+
return col;
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
function diffTable(then, now) {
|
|
209
|
+
const columns = now.columns.length ? now.columns : then.columns;
|
|
210
|
+
const col = rowKeyColumn(then.rows, now.rows, columns);
|
|
211
|
+
const keyOf = (r, i) => col ? String(own(r, col)) : `#${i + 1}`;
|
|
212
|
+
const thenMap = new Map(then.rows.map((r, i) => [keyOf(r, i), r]));
|
|
213
|
+
const nowMap = new Map(now.rows.map((r, i) => [keyOf(r, i), r]));
|
|
214
|
+
const added = [];
|
|
215
|
+
const removed = [];
|
|
216
|
+
const changed = [];
|
|
217
|
+
for (const [k, r] of nowMap) {
|
|
218
|
+
const old = thenMap.get(k);
|
|
219
|
+
if (!old) {
|
|
220
|
+
added.push({ key: k, fields: [] });
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const fields = [
|
|
224
|
+
...new Set([...Object.keys(old), ...Object.keys(r)]),
|
|
225
|
+
].filter((f) => !jsonEqual(own(old, f), own(r, f)));
|
|
226
|
+
if (fields.length)
|
|
227
|
+
changed.push({ key: k, fields });
|
|
228
|
+
}
|
|
229
|
+
for (const k of thenMap.keys()) {
|
|
230
|
+
if (!nowMap.has(k))
|
|
231
|
+
removed.push({ key: k, fields: [] });
|
|
232
|
+
}
|
|
233
|
+
const total = added.length + removed.length + changed.length;
|
|
234
|
+
let budget = MAX_DIFF_ENTRIES;
|
|
235
|
+
const take = (list) => {
|
|
236
|
+
const out = list.slice(0, Math.max(0, budget));
|
|
237
|
+
budget -= out.length;
|
|
238
|
+
return out;
|
|
239
|
+
};
|
|
240
|
+
return {
|
|
241
|
+
added: take(added),
|
|
242
|
+
removed: take(removed),
|
|
243
|
+
changed: take(changed),
|
|
244
|
+
truncated: Math.max(0, total - MAX_DIFF_ENTRIES),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function leaves(v, path, out, depth = 0) {
|
|
248
|
+
if (out.size > 2000 || depth > 12)
|
|
249
|
+
return;
|
|
250
|
+
if (v === null || ["string", "number", "boolean"].includes(typeof v)) {
|
|
251
|
+
out.set(path || "$", v);
|
|
252
|
+
}
|
|
253
|
+
else if (Array.isArray(v)) {
|
|
254
|
+
v.forEach((el, i) => leaves(el, `${path}[${i}]`, out, depth + 1));
|
|
255
|
+
}
|
|
256
|
+
else if (isRecord(v)) {
|
|
257
|
+
for (const k of Object.keys(v))
|
|
258
|
+
leaves(v[k], path ? `${path}.${k}` : k, out, depth + 1);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function diffLeaves(then, now) {
|
|
262
|
+
const a = new Map();
|
|
263
|
+
const b = new Map();
|
|
264
|
+
leaves(then, "", a);
|
|
265
|
+
leaves(now, "", b);
|
|
266
|
+
const all = [];
|
|
267
|
+
for (const p of new Set([...b.keys(), ...a.keys()])) {
|
|
268
|
+
const t = a.get(p);
|
|
269
|
+
const n = b.get(p);
|
|
270
|
+
if (t === n)
|
|
271
|
+
continue;
|
|
272
|
+
const tn = finite(t);
|
|
273
|
+
const nn = finite(n);
|
|
274
|
+
all.push({
|
|
275
|
+
path: p,
|
|
276
|
+
then: t,
|
|
277
|
+
now: n,
|
|
278
|
+
delta: tn !== null && nn !== null ? nn - tn : null,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
leaves: all.slice(0, MAX_DIFF_ENTRIES),
|
|
283
|
+
truncated: Math.max(0, all.length - MAX_DIFF_ENTRIES),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Diff two live-data blobs key by key (`then` → `now`). Keys are reported in
|
|
288
|
+
* `now`'s order, then keys only `then` had. A non-object side reads as {}.
|
|
289
|
+
*/
|
|
290
|
+
export function diffData(then, now) {
|
|
291
|
+
const a = isRecord(then) ? then : {};
|
|
292
|
+
const b = isRecord(now) ? now : {};
|
|
293
|
+
const keys = [
|
|
294
|
+
...Object.keys(b),
|
|
295
|
+
...Object.keys(a).filter((k) => own(b, k) === undefined),
|
|
296
|
+
];
|
|
297
|
+
const out = [];
|
|
298
|
+
for (const key of keys) {
|
|
299
|
+
const t = own(a, key);
|
|
300
|
+
const n = own(b, key);
|
|
301
|
+
if (t === undefined) {
|
|
302
|
+
out.push({ key, status: "added" });
|
|
303
|
+
}
|
|
304
|
+
else if (n === undefined) {
|
|
305
|
+
out.push({ key, status: "removed" });
|
|
306
|
+
}
|
|
307
|
+
else if (jsonEqual(t, n)) {
|
|
308
|
+
out.push({ key, status: "same" });
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
const kt = kpiCards(t);
|
|
312
|
+
const kn = kpiCards(n);
|
|
313
|
+
const tt = tableRows(t);
|
|
314
|
+
const tn = tableRows(n);
|
|
315
|
+
if (kt && kn) {
|
|
316
|
+
out.push({
|
|
317
|
+
key,
|
|
318
|
+
status: "changed",
|
|
319
|
+
shape: "kpi",
|
|
320
|
+
kpis: diffKpis(kt, kn),
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else if (tt && tn) {
|
|
324
|
+
out.push({
|
|
325
|
+
key,
|
|
326
|
+
status: "changed",
|
|
327
|
+
shape: "table",
|
|
328
|
+
...diffTable(tt, tn),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
out.push({
|
|
333
|
+
key,
|
|
334
|
+
status: "changed",
|
|
335
|
+
shape: "value",
|
|
336
|
+
...diffLeaves(t, n),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
keys: out,
|
|
343
|
+
changedKeys: out.filter((d) => d.status !== "same").length,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
/** "+4.2%", "−1,203", "0" — a signed delta for display (U+2212 minus). */
|
|
347
|
+
export function formatDelta(delta, pct = null) {
|
|
348
|
+
const sign = delta > 0 ? "+" : delta < 0 ? "−" : "";
|
|
349
|
+
const abs = Math.abs(delta);
|
|
350
|
+
const num = abs.toLocaleString("en-US", { maximumFractionDigits: 2 });
|
|
351
|
+
const p = pct === null
|
|
352
|
+
? ""
|
|
353
|
+
: ` (${sign}${Math.abs(pct * 100).toLocaleString("en-US", { maximumFractionDigits: 1 })}%)`;
|
|
354
|
+
return `${sign}${num}${p}`;
|
|
355
|
+
}
|
|
356
|
+
/** Parse a `?at=` query value: ISO-8601 or epoch ms. NaN when neither. */
|
|
357
|
+
export function parseInstant(raw) {
|
|
358
|
+
if (raw === null || raw.trim() === "")
|
|
359
|
+
return NaN;
|
|
360
|
+
if (/^\d{10,16}$/.test(raw.trim()))
|
|
361
|
+
return Number(raw.trim());
|
|
362
|
+
return Date.parse(raw);
|
|
363
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `jatui/artifact-blocks` — ONE renderer for blocks artifacts, shared by MOS
|
|
3
|
+
* and the jat IDE (epic jatui-936iz; core jatui-vsuzi).
|
|
4
|
+
*
|
|
5
|
+
* <BlocksArtifactView {artifactId} {version} {title} {summary} {byline}
|
|
6
|
+
* {spec} adapter={host} {savedBlocks} {onSaveBlock} … />
|
|
7
|
+
*
|
|
8
|
+
* or the renderer alone: `<BlockRenderer {spec} {artifactId} {version}
|
|
9
|
+
* adapter={host} />`. Everything host-specific is the `HostAdapter`
|
|
10
|
+
* (types.ts); the contract is CONTRACT.md in this folder.
|
|
11
|
+
*/
|
|
12
|
+
export { default as BlocksArtifactView } from "./BlocksArtifactView.svelte";
|
|
13
|
+
export { default as BlockRenderer } from "./BlockRenderer.svelte";
|
|
14
|
+
export { default as BlockVerdict } from "./BlockVerdict.svelte";
|
|
15
|
+
export { default as BlockComments } from "./BlockComments.svelte";
|
|
16
|
+
export { default as CommentPill } from "./CommentPill.svelte";
|
|
17
|
+
export { default as SectionTools } from "./SectionTools.svelte";
|
|
18
|
+
export { default as FoldedRounds } from "./FoldedRounds.svelte";
|
|
19
|
+
export { default as HistoryScrubber } from "./HistoryScrubber.svelte";
|
|
20
|
+
export { default as Markdown } from "./Markdown.svelte";
|
|
21
|
+
export { default as NoteComposer } from "./NoteComposer.svelte";
|
|
22
|
+
export { default as PlainComposer } from "./PlainComposer.svelte";
|
|
23
|
+
export { default as AttachmentChip } from "./AttachmentChip.svelte";
|
|
24
|
+
export { registerBlocks, blockDef, allBlockDefs, validateBlocksSpec, } from "./registry.js";
|
|
25
|
+
export { BUILTIN_BLOCKS, PENDING_BLOCK_TYPES, BLOCK_GROUPS } from "./builtins.js";
|
|
26
|
+
export { default as markdownBlock } from "./blocks/markdown/block.js";
|
|
27
|
+
export { markdownSchema, type MarkdownParams } from "./blocks/markdown/schema.js";
|
|
28
|
+
export { urlSchema, optionalUrlSchema, linkUrlSchema, isSafeLinkUrl, isSafeResourceUrl, toneSchema, TONE_TOKENS, shortTextSchema, longTextSchema, isoDateSchema, shortTextList, type ToneToken, } from "./params.js";
|
|
29
|
+
export { normalizeContractBlocks, blockLinkErrors, blockTasksOf, decisionExtras, decisionMetaSchema, decisionSectionsSchema, decisionPrimaryActionSchema, decisionTitleSchema, blockGroupSchema, DECISION_BODY_BUDGET, } from "./contractBlocks.js";
|
|
30
|
+
export { renderBlockMarkdown, renderBlockMarkdownInline, looksLikeMarkdown, } from "./blocks/markdown/render.js";
|
|
31
|
+
export { coerceBlocksSpec, reviewKey, ITEM_REVIEW_BLOCK_TYPES, isItemReviewBlock, isDecisionBlock, takesBlockVerdict, OTHER_ID, decisionCardsOf, verdictsFromBlocks, blockReviewStateOf, reviewItemsOf, BLOCKS_VOCABULARY, wordFor, countReviewUnits, pageReviewProgress, openReviewUnits, itemVerdictsOf, coerceSentAnswer, changedSinceSend, sentAnswerLine, type DecisionCard, type DecisionOption, type ReviewUnitLine, type ReviewUnitCounts, type ReviewProgressProps, type PageReviewProgress, type OpenReviewUnit, type ChangedSinceSend, } from "./review.js";
|
|
32
|
+
export { resolveBlockParams, formatDataAge, normalizeDataPublish, serializedBytes, MAX_DATA_BYTES, type DataPublishMode, type ResolvedBlockParams, } from "./liveData.js";
|
|
33
|
+
export { createLiveDataPoller, dataAgeLine, dataAgeTitle, type LiveDataPoller, } from "./liveDataPoller.js";
|
|
34
|
+
export * from "./history.js";
|
|
35
|
+
export { createOpenNav, revealUnit, type JumpUnit } from "./openNav.js";
|
|
36
|
+
export { createPageReviewKeys, isPageChromeTarget } from "./pageReviewKeys.js";
|
|
37
|
+
export { AUTO_SEND_DELAY_MS, createAutoSend } from "./autoSend.js";
|
|
38
|
+
export { provideHostAdapter, hostAdapter, hostServices, HOST_ADAPTER_KEY, } from "./adapter.js";
|
|
39
|
+
export { provideBlockListen, blockListen, BLOCK_LISTEN_KEY, type BlockListenContext, } from "./listen/context.js";
|
|
40
|
+
export type * from "./types.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `jatui/artifact-blocks` — ONE renderer for blocks artifacts, shared by MOS
|
|
3
|
+
* and the jat IDE (epic jatui-936iz; core jatui-vsuzi).
|
|
4
|
+
*
|
|
5
|
+
* <BlocksArtifactView {artifactId} {version} {title} {summary} {byline}
|
|
6
|
+
* {spec} adapter={host} {savedBlocks} {onSaveBlock} … />
|
|
7
|
+
*
|
|
8
|
+
* or the renderer alone: `<BlockRenderer {spec} {artifactId} {version}
|
|
9
|
+
* adapter={host} />`. Everything host-specific is the `HostAdapter`
|
|
10
|
+
* (types.ts); the contract is CONTRACT.md in this folder.
|
|
11
|
+
*/
|
|
12
|
+
// Views
|
|
13
|
+
export { default as BlocksArtifactView } from "./BlocksArtifactView.svelte";
|
|
14
|
+
export { default as BlockRenderer } from "./BlockRenderer.svelte";
|
|
15
|
+
export { default as BlockVerdict } from "./BlockVerdict.svelte";
|
|
16
|
+
export { default as BlockComments } from "./BlockComments.svelte";
|
|
17
|
+
export { default as CommentPill } from "./CommentPill.svelte";
|
|
18
|
+
export { default as SectionTools } from "./SectionTools.svelte";
|
|
19
|
+
export { default as FoldedRounds } from "./FoldedRounds.svelte";
|
|
20
|
+
export { default as HistoryScrubber } from "./HistoryScrubber.svelte";
|
|
21
|
+
export { default as Markdown } from "./Markdown.svelte";
|
|
22
|
+
export { default as NoteComposer } from "./NoteComposer.svelte";
|
|
23
|
+
export { default as PlainComposer } from "./PlainComposer.svelte";
|
|
24
|
+
export { default as AttachmentChip } from "./AttachmentChip.svelte";
|
|
25
|
+
// Catalog
|
|
26
|
+
export { registerBlocks, blockDef, allBlockDefs, validateBlocksSpec, } from "./registry.js";
|
|
27
|
+
export { BUILTIN_BLOCKS, PENDING_BLOCK_TYPES, BLOCK_GROUPS } from "./builtins.js";
|
|
28
|
+
export { default as markdownBlock } from "./blocks/markdown/block.js";
|
|
29
|
+
export { markdownSchema } from "./blocks/markdown/schema.js";
|
|
30
|
+
// Params + the provider contract
|
|
31
|
+
export { urlSchema, optionalUrlSchema, linkUrlSchema, isSafeLinkUrl, isSafeResourceUrl, toneSchema, TONE_TOKENS, shortTextSchema, longTextSchema, isoDateSchema, shortTextList, } from "./params.js";
|
|
32
|
+
export { normalizeContractBlocks, blockLinkErrors, blockTasksOf, decisionExtras, decisionMetaSchema, decisionSectionsSchema, decisionPrimaryActionSchema, decisionTitleSchema, blockGroupSchema, DECISION_BODY_BUDGET, } from "./contractBlocks.js";
|
|
33
|
+
// Markdown
|
|
34
|
+
export { renderBlockMarkdown, renderBlockMarkdownInline, looksLikeMarkdown, } from "./blocks/markdown/render.js";
|
|
35
|
+
// Review math
|
|
36
|
+
export { coerceBlocksSpec, reviewKey, ITEM_REVIEW_BLOCK_TYPES, isItemReviewBlock, isDecisionBlock, takesBlockVerdict, OTHER_ID, decisionCardsOf, verdictsFromBlocks, blockReviewStateOf, reviewItemsOf, BLOCKS_VOCABULARY, wordFor, countReviewUnits, pageReviewProgress, openReviewUnits, itemVerdictsOf, coerceSentAnswer, changedSinceSend, sentAnswerLine, } from "./review.js";
|
|
37
|
+
// Live data, history, navigation, keys
|
|
38
|
+
export { resolveBlockParams, formatDataAge, normalizeDataPublish, serializedBytes, MAX_DATA_BYTES, } from "./liveData.js";
|
|
39
|
+
export { createLiveDataPoller, dataAgeLine, dataAgeTitle, } from "./liveDataPoller.js";
|
|
40
|
+
export * from "./history.js";
|
|
41
|
+
export { createOpenNav, revealUnit } from "./openNav.js";
|
|
42
|
+
export { createPageReviewKeys, isPageChromeTarget } from "./pageReviewKeys.js";
|
|
43
|
+
export { AUTO_SEND_DELAY_MS, createAutoSend } from "./autoSend.js";
|
|
44
|
+
// Host wiring
|
|
45
|
+
export { provideHostAdapter, hostAdapter, hostServices, HOST_ADAPTER_KEY, } from "./adapter.js";
|
|
46
|
+
export { provideBlockListen, blockListen, BLOCK_LISTEN_KEY, } from "./listen/context.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact blocks — the Listen context (origin mos-8vdg9; jatui-vsuzi).
|
|
3
|
+
*
|
|
4
|
+
* A block's own Listen control must know WHICH surface its segments live in,
|
|
5
|
+
* but blocks are generic components: the host owns that. In jatui the host
|
|
6
|
+
* hands its Listen control over as a snippet — `HostAdapter.listen` — which
|
|
7
|
+
* SectionTools renders with the block's coordinates ({ group, label,
|
|
8
|
+
* anchor }). jatui's own ListenControl fits inside it; MOS keeps its
|
|
9
|
+
* coordinate-based player.
|
|
10
|
+
*
|
|
11
|
+
* The adapter's `listen` is the default source; a host that wants Listen
|
|
12
|
+
* for only PART of a page (or a test mounting one block) can override it
|
|
13
|
+
* below any point with provideBlockListen(). Neither → no Listen control
|
|
14
|
+
* (share link, print).
|
|
15
|
+
*/
|
|
16
|
+
import { type Snippet } from "svelte";
|
|
17
|
+
import type { BlockListenArgs } from "../types.js";
|
|
18
|
+
export interface BlockListenContext {
|
|
19
|
+
/** Renders the host's Listen control for one block; null = none here. */
|
|
20
|
+
render: Snippet<[BlockListenArgs]> | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The context key itself, exported for tests that mount a block directly
|
|
24
|
+
* (mount(Component, { context: new Map([[BLOCK_LISTEN_KEY, …]]) })).
|
|
25
|
+
*/
|
|
26
|
+
export declare const BLOCK_LISTEN_KEY: symbol;
|
|
27
|
+
/** Host-side: publish the Listen renderer to every block below. */
|
|
28
|
+
export declare function provideBlockListen(ctx: BlockListenContext): void;
|
|
29
|
+
/** Block-side: the Listen renderer, or null when this host offers none. */
|
|
30
|
+
export declare function blockListen(): BlockListenContext | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact blocks — the Listen context (origin mos-8vdg9; jatui-vsuzi).
|
|
3
|
+
*
|
|
4
|
+
* A block's own Listen control must know WHICH surface its segments live in,
|
|
5
|
+
* but blocks are generic components: the host owns that. In jatui the host
|
|
6
|
+
* hands its Listen control over as a snippet — `HostAdapter.listen` — which
|
|
7
|
+
* SectionTools renders with the block's coordinates ({ group, label,
|
|
8
|
+
* anchor }). jatui's own ListenControl fits inside it; MOS keeps its
|
|
9
|
+
* coordinate-based player.
|
|
10
|
+
*
|
|
11
|
+
* The adapter's `listen` is the default source; a host that wants Listen
|
|
12
|
+
* for only PART of a page (or a test mounting one block) can override it
|
|
13
|
+
* below any point with provideBlockListen(). Neither → no Listen control
|
|
14
|
+
* (share link, print).
|
|
15
|
+
*/
|
|
16
|
+
import { getContext, setContext } from "svelte";
|
|
17
|
+
const KEY = Symbol("artifact-blocks-listen");
|
|
18
|
+
/**
|
|
19
|
+
* The context key itself, exported for tests that mount a block directly
|
|
20
|
+
* (mount(Component, { context: new Map([[BLOCK_LISTEN_KEY, …]]) })).
|
|
21
|
+
*/
|
|
22
|
+
export const BLOCK_LISTEN_KEY = KEY;
|
|
23
|
+
/** Host-side: publish the Listen renderer to every block below. */
|
|
24
|
+
export function provideBlockListen(ctx) {
|
|
25
|
+
setContext(KEY, ctx);
|
|
26
|
+
}
|
|
27
|
+
/** Block-side: the Listen renderer, or null when this host offers none. */
|
|
28
|
+
export function blockListen() {
|
|
29
|
+
return getContext(KEY) ?? null;
|
|
30
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live data for blocks artifacts (origin mos-0ninw, phase 3 of MOS epic
|
|
3
|
+
* mos-m1qrx).
|
|
4
|
+
*
|
|
5
|
+
* A blocks page publishes LAYOUT once; its NUMBERS move without a
|
|
6
|
+
* republish. The host keeps a per-artifact key→value data map (MOS:
|
|
7
|
+
* `artifacts.data`, `mos-artifact data`) — version-independent, so a cron
|
|
8
|
+
* or generator can refresh a dashboard while its layout stays put.
|
|
9
|
+
*
|
|
10
|
+
* The binding, on the HOST side (BlockRenderer):
|
|
11
|
+
*
|
|
12
|
+
* - a block whose def declares `dataParam: "dataKey"` and whose params
|
|
13
|
+
* set that key (e.g. `dataKey: "soak"`) renders from `data.soak`
|
|
14
|
+
* INSTEAD of its inline params, once a value exists for that key;
|
|
15
|
+
* - before the first data publish (or with the key absent), the block
|
|
16
|
+
* renders its inline params — a fresh page is never blank, and a
|
|
17
|
+
* publisher can push data at their own pace;
|
|
18
|
+
* - the live value REPLACES the params object wholesale, then goes
|
|
19
|
+
* through the same zod schema as publish-time params. Data is as
|
|
20
|
+
* untrusted as params are: a value that fails the schema renders the
|
|
21
|
+
* block's error card naming the dataKey — never a silent fallback to
|
|
22
|
+
* stale inline numbers.
|
|
23
|
+
*
|
|
24
|
+
* This module is PURE (no db import): BlockRenderer renders it into the
|
|
25
|
+
* browser, a host's service and routes import it on the server. Storage is
|
|
26
|
+
* the host's.
|
|
27
|
+
*/
|
|
28
|
+
import type { ArtifactBlockDef } from "./types";
|
|
29
|
+
/**
|
|
30
|
+
* Largest serialized artifacts.data accepted after a write. Generous for a
|
|
31
|
+
* real dashboard (thousands of table rows), small enough that a runaway
|
|
32
|
+
* generator cannot balloon a page's poll payload. The service enforces it
|
|
33
|
+
* inside the UPDATE itself — a write that would exceed the cap changes
|
|
34
|
+
* NOTHING (no partial merge, no data_updated_at bump).
|
|
35
|
+
*/
|
|
36
|
+
export declare const MAX_DATA_BYTES: number;
|
|
37
|
+
export declare function serializedBytes(v: unknown): number;
|
|
38
|
+
export type DataPublishMode = "merge" | "key" | "replace";
|
|
39
|
+
interface NormalizedDataPublish {
|
|
40
|
+
mode: DataPublishMode;
|
|
41
|
+
key: string | null;
|
|
42
|
+
/** The value to store: the whole blob (merge/replace) or the key's value. */
|
|
43
|
+
value: unknown;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate + normalize a data publish. Throws with a message an agent can
|
|
47
|
+
* act on; the route turns that into a 400. `undefined` incoming data is a
|
|
48
|
+
* programmer error (the body always parses to something) and is refused like
|
|
49
|
+
* any other invalid input.
|
|
50
|
+
*/
|
|
51
|
+
export declare function normalizeDataPublish(input: {
|
|
52
|
+
data: unknown;
|
|
53
|
+
key?: unknown;
|
|
54
|
+
replace?: unknown;
|
|
55
|
+
}): NormalizedDataPublish;
|
|
56
|
+
export interface ResolvedBlockParams {
|
|
57
|
+
/** What the block renders: the live value when one exists, else inline. */
|
|
58
|
+
params: unknown;
|
|
59
|
+
/** The dataKey the block ASKED for (null when it did not opt in). */
|
|
60
|
+
dataKey: string | null;
|
|
61
|
+
/** True when the rendered params ARE the live value. */
|
|
62
|
+
fromData: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The dataParam binding. `def.dataParam` names the params field holding the
|
|
66
|
+
* data key; when that field names a key WITH a published value, the live
|
|
67
|
+
* value replaces the params wholesale. Everything else renders inline:
|
|
68
|
+
* no opt-in, no published value, or a key that exists only on the prototype
|
|
69
|
+
* chain (hasOwn guard).
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveBlockParams(def: Pick<ArtifactBlockDef, "dataParam"> | undefined, rawParams: unknown, data: Record<string, unknown>): ResolvedBlockParams;
|
|
72
|
+
/**
|
|
73
|
+
* The subtle freshness line: "just now" → "42s ago" → "2m ago" → "3h ago" →
|
|
74
|
+
* "5d ago". Empty string when there is no data yet (the line does not render
|
|
75
|
+
* at all).
|
|
76
|
+
*/
|
|
77
|
+
export declare function formatDataAge(updatedAt: string | number | Date | null | undefined, now: number | Date): string;
|
|
78
|
+
export {};
|