@dxos/ui-editor 0.0.0 → 0.8.4-main.05e74ebcff
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/index.mjs +8657 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/types/index.mjs +33 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +8659 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/types/index.mjs +35 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/defaults.d.ts +6 -0
- package/dist/types/src/defaults.d.ts.map +1 -0
- package/dist/types/src/extensions/annotations.d.ts +9 -0
- package/dist/types/src/extensions/annotations.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts +17 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +23 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts +4 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts +4 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/defs.d.ts +17 -0
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts +2 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/sync.d.ts +17 -0
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +6 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts +5 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts +31 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts +46 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/index.d.ts +3 -0
- package/dist/types/src/extensions/awareness/index.d.ts.map +1 -0
- package/dist/types/src/extensions/blast.d.ts +25 -0
- package/dist/types/src/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/extensions/blocks.d.ts +2 -0
- package/dist/types/src/extensions/blocks.d.ts.map +1 -0
- package/dist/types/src/extensions/bookmarks.d.ts +12 -0
- package/dist/types/src/extensions/bookmarks.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts +90 -0
- package/dist/types/src/extensions/comments.d.ts.map +1 -0
- package/dist/types/src/extensions/debug.d.ts +3 -0
- package/dist/types/src/extensions/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/dnd.d.ts +9 -0
- package/dist/types/src/extensions/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.d.ts +88 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +7 -0
- package/dist/types/src/extensions/focus.d.ts.map +1 -0
- package/dist/types/src/extensions/folding.d.ts +6 -0
- package/dist/types/src/extensions/folding.d.ts.map +1 -0
- package/dist/types/src/extensions/hashtag.d.ts +3 -0
- package/dist/types/src/extensions/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +30 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/extensions/json.d.ts +7 -0
- package/dist/types/src/extensions/json.d.ts.map +1 -0
- package/dist/types/src/extensions/listener.d.ts +13 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/action.d.ts +12 -0
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts +25 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.d.ts +10 -0
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/debug.d.ts +11 -0
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts +25 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +63 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts +37 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts +7 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +10 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/link.d.ts +7 -0
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/styles.d.ts +4 -0
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts +8 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/mention.d.ts +7 -0
- package/dist/types/src/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/extensions/modal.d.ts +7 -0
- package/dist/types/src/extensions/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/modes.d.ts +10 -0
- package/dist/types/src/extensions/modes.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
- package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
- package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/index.d.ts +4 -0
- package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts +11 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/index.d.ts +2 -0
- package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +34 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.d.ts +21 -0
- package/dist/types/src/extensions/replacer.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.test.d.ts +2 -0
- package/dist/types/src/extensions/replacer.test.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts +75 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +5 -0
- package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts +24 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/state.d.ts +2 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts +10 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +7 -0
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +117 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +8 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/styles/index.d.ts +2 -0
- package/dist/types/src/styles/index.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts +58 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +21 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/src/util/cursor.d.ts +31 -0
- package/dist/types/src/util/cursor.d.ts.map +1 -0
- package/dist/types/src/util/debug.d.ts +17 -0
- package/dist/types/src/util/debug.d.ts.map +1 -0
- package/dist/types/src/util/decorations.d.ts +4 -0
- package/dist/types/src/util/decorations.d.ts.map +1 -0
- package/dist/types/src/util/dom.d.ts +10 -0
- package/dist/types/src/util/dom.d.ts.map +1 -0
- package/dist/types/src/util/facet.d.ts +3 -0
- package/dist/types/src/util/facet.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +7 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/util.d.ts +8 -0
- package/dist/types/src/util/util.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +43 -44
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +37 -11
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/blocks.ts +5 -5
- package/src/extensions/comments.ts +5 -6
- package/src/extensions/dnd.ts +2 -2
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +32 -15
- package/src/extensions/folding.ts +5 -22
- package/src/extensions/index.ts +2 -3
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +15 -12
- package/src/extensions/markdown/formatting.ts +5 -10
- package/src/extensions/markdown/highlight.ts +15 -7
- package/src/extensions/markdown/link.ts +27 -33
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +42 -9
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +3 -4
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +62 -15
- package/src/extensions/scrolling/auto-scroll.ts +244 -0
- package/src/extensions/scrolling/crawler.ts +263 -0
- package/src/extensions/scrolling/index.ts +8 -0
- package/src/extensions/scrolling/scroll-past-end.ts +32 -0
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +186 -35
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/index.ts +0 -2
- package/src/styles/theme.ts +125 -33
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/src/extensions/autoscroll.ts +0 -165
- package/src/extensions/scrolling.ts +0 -189
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Extension, StateEffect, StateField } from '@codemirror/state';
|
|
6
|
+
import { Decoration, type DecorationSet, EditorView, ViewPlugin } from '@codemirror/view';
|
|
7
|
+
|
|
8
|
+
const DEFAULT_REMOVAL_DELAY = 5_000; // ms.
|
|
9
|
+
const DEFAULT_COALESCE_WINDOW = 100; // ms.
|
|
10
|
+
const CLEANUP_INTERVAL = 1_000; // ms.
|
|
11
|
+
|
|
12
|
+
export type FaderOptions = {
|
|
13
|
+
/** Time window in ms to coalesce adjacent appends into a single decoration. */
|
|
14
|
+
coalesce?: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Extension that decorates appended text with a fade-in effect.
|
|
19
|
+
* Adjacent appends within the coalesce window are merged into a single decoration.
|
|
20
|
+
* Decorations are queued with an expiry and removed by a timer.
|
|
21
|
+
*/
|
|
22
|
+
export const fader = (options: FaderOptions = {}): Extension => {
|
|
23
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
24
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
25
|
+
|
|
26
|
+
let lastCount = -1;
|
|
27
|
+
const log = (expiries: number[]) => {
|
|
28
|
+
if (expiries.length !== lastCount) {
|
|
29
|
+
lastCount = expiries.length;
|
|
30
|
+
// console.log('[fader] decorations:', lastCount);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Effect to remove all expired decorations.
|
|
35
|
+
const dequeue = StateEffect.define<number>();
|
|
36
|
+
|
|
37
|
+
// FIFO of expiry timestamps paired with a decoration set.
|
|
38
|
+
// Tracks `batchStart` — the time the current coalesce batch began.
|
|
39
|
+
type FaderState = {
|
|
40
|
+
decorations: DecorationSet;
|
|
41
|
+
expiries: number[];
|
|
42
|
+
batchStart: number;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const fadeField = StateField.define<FaderState>({
|
|
46
|
+
create: () => ({ decorations: Decoration.none, expiries: [], batchStart: 0 }),
|
|
47
|
+
update: ({ decorations, expiries, batchStart }, tr) => {
|
|
48
|
+
// Remove expired entries by count (FIFO order matches decoration insertion order).
|
|
49
|
+
for (const effect of tr.effects) {
|
|
50
|
+
if (effect.is(dequeue)) {
|
|
51
|
+
const now = effect.value;
|
|
52
|
+
let removeCount = 0;
|
|
53
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now) {
|
|
54
|
+
removeCount++;
|
|
55
|
+
}
|
|
56
|
+
if (removeCount > 0) {
|
|
57
|
+
expiries = expiries.slice(removeCount);
|
|
58
|
+
let skipped = 0;
|
|
59
|
+
decorations = decorations.update({
|
|
60
|
+
filter: () => {
|
|
61
|
+
if (skipped < removeCount) {
|
|
62
|
+
skipped++;
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!tr.docChanged) {
|
|
73
|
+
log(expiries);
|
|
74
|
+
return { decorations, expiries, batchStart };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Reset when document is cleared or fully replaced.
|
|
78
|
+
let isReset = tr.state.doc.length === 0;
|
|
79
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
80
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
81
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
82
|
+
isReset = true;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (isReset) {
|
|
87
|
+
log([]);
|
|
88
|
+
return { decorations: Decoration.none, expiries: [], batchStart: 0 };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Collect appended ranges.
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
const add: { from: number; to: number }[] = [];
|
|
94
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
95
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
96
|
+
add.push({ from: fromB, to: toB });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
if (add.length > 0) {
|
|
101
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
102
|
+
if (canCoalesce) {
|
|
103
|
+
// Extend the last decoration: remove it, then add a merged one.
|
|
104
|
+
let lastFrom = -1;
|
|
105
|
+
let lastTo = -1;
|
|
106
|
+
decorations.between(0, tr.state.doc.length, (from, to) => {
|
|
107
|
+
lastFrom = from;
|
|
108
|
+
lastTo = to;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (lastFrom >= 0) {
|
|
112
|
+
decorations = decorations.update({
|
|
113
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
117
|
+
const mergedTo = add[add.length - 1].to;
|
|
118
|
+
decorations = decorations.update({
|
|
119
|
+
add: [Decoration.mark({ class: 'cm-fader' }).range(mergedFrom, mergedTo)],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Update the last expiry rather than adding a new one.
|
|
123
|
+
expiries = [...expiries.slice(0, -1), now + removalDelay];
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
// New batch — record when it started.
|
|
127
|
+
batchStart = now;
|
|
128
|
+
expiries = [...expiries, now + removalDelay];
|
|
129
|
+
decorations = decorations.update({
|
|
130
|
+
add: add.map(({ from, to }) => Decoration.mark({ class: 'cm-fader' }).range(from, to)),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
log(expiries);
|
|
136
|
+
return { decorations, expiries, batchStart };
|
|
137
|
+
},
|
|
138
|
+
provide: (f) => EditorView.decorations.from(f, (value) => value.decorations),
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Timer that schedules removal based on the next pending expiry.
|
|
142
|
+
const cleanup = ViewPlugin.fromClass(
|
|
143
|
+
class {
|
|
144
|
+
#timer: ReturnType<typeof setTimeout> | undefined;
|
|
145
|
+
|
|
146
|
+
constructor(private view: EditorView) {
|
|
147
|
+
this.#schedule();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
update() {
|
|
151
|
+
this.#schedule();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#schedule() {
|
|
155
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
156
|
+
if (expiries.length === 0) {
|
|
157
|
+
clearTimeout(this.#timer);
|
|
158
|
+
this.#timer = undefined;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (this.#timer !== undefined) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Wait at least CLEANUP_INTERVAL after the oldest expiry to batch removals.
|
|
167
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
168
|
+
this.#timer = setTimeout(() => {
|
|
169
|
+
this.#timer = undefined;
|
|
170
|
+
this.view.dispatch({ effects: dequeue.of(Date.now()) });
|
|
171
|
+
}, delay);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
destroy() {
|
|
175
|
+
clearTimeout(this.#timer);
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return [
|
|
181
|
+
fadeField,
|
|
182
|
+
cleanup,
|
|
183
|
+
EditorView.theme({
|
|
184
|
+
'.cm-fader': {
|
|
185
|
+
animation: 'fader 1s ease-out forwards',
|
|
186
|
+
},
|
|
187
|
+
'@keyframes fader': {
|
|
188
|
+
'0%': {
|
|
189
|
+
textShadow: '0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)',
|
|
190
|
+
},
|
|
191
|
+
'100%': {},
|
|
192
|
+
},
|
|
193
|
+
}),
|
|
194
|
+
];
|
|
195
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<prompt>summarize the posts</prompt>
|
|
2
|
+
<reasoning>The user wants me to summarize the posts related to the magazine in context. Let me first load the magazine object to understand its structure, and then list the candidate posts.</reasoning>
|
|
3
|
+
<status>Loading the magazine and listing candidate posts…</status>
|
|
4
|
+
<toolCall id="toolu_01WMMcsaHxTvuGxcMh2CkfL4" />
|
|
5
|
+
<toolCall id="toolu_01CxWNvXZ4jExfLEJumfMzqm" />
|
|
6
|
+
<reasoning>The magazine has 10 posts already curated, and there are no uncurated candidate posts. The user wants me to summarize the posts that are already in the magazine. Let me load them.</reasoning>
|
|
7
|
+
<status>No uncurated candidates — loading the 10 posts already in the magazine…</status>
|
|
8
|
+
<toolCall id="toolu_0152ftz33GL5M1DDi8GGDHi2" />
|
|
9
|
+
<reasoning>The magazine has 10 posts, but several are duplicates. Let me deduplicate by title/guid and summarize the unique articles. Unique articles:
|
|
10
|
+
|
|
11
|
+
1. "FBI affidavit quotes White House press dinner shooting suspect expressing rage at 'a pedophile, rapist and traitor' – US politics live" - About Cole Allen's manifesto and charges, plus King Charles visiting Trump at the White House.
|
|
12
|
+
2. "Australia news live: UK inquiry says 'cracks already beginning to show' on Aukus; search for missing five-year-old near Alice Springs grows" - Live blog covering Aukus inquiry, David Brat nominated as ambassador to Australia, fuel reserve crisis.
|
|
13
|
+
3. "Rebel Wilson gives evidence in high-profile defamation case against star of directorial debut" - Rebel Wilson testifying in defamation case brought by Charlotte MacInnes.
|
|
14
|
+
4. "Baby on board: US woman gives birth on Delta flight" - Ashley Blair delivered her baby aboard a Delta flight traveling from Atlanta to Portland.
|
|
15
|
+
5. "'Shortcomings and failures' could sink Aukus nuclear submarines plan, UK inquiry warns" - A UK House of Commons defence committee report identifies significant funding gaps threatening the Aukus submarine program.</reasoning>
|
|
16
|
+
Here's a summary of the **5 unique articles** currently in the magazine (some posts are duplicates):
|
|
17
|
+
|
|
18
|
+
6. **FBI affidavit quotes White House press dinner shooting suspect**
|
|
19
|
+
Federal charges filed against Cole Allen include excerpts from a manifesto he emailed to family and friends before attempting to charge into the White House Correspondents' Dinner. Separately, King Charles and Queen Camilla visited Donald Trump at the White House for tea and a beehive tour.
|
|
20
|
+
|
|
21
|
+
7. **Australia news live: Aukus 'cracks' & missing child search**
|
|
22
|
+
A UK House of Commons inquiry reveals "shortcomings and failings" in the Aukus submarine program. Also covered: David Brat nominated as the next US ambassador to Australia, and a push to extend Australia's fuel reserves from 30 to 60 days amid rising security concerns.
|
|
23
|
+
|
|
24
|
+
8. **Rebel Wilson testifies in defamation case**
|
|
25
|
+
Hollywood star Rebel Wilson gave evidence in a defamation lawsuit brought by Charlotte MacInnes, the lead actor of Wilson's directorial debut _The Deb_. The case centres on claims MacInnes confided to Wilson about being uncomfortable with a bathing request from a colleague.
|
|
26
|
+
|
|
27
|
+
9. **Baby born on Delta flight**
|
|
28
|
+
Passenger Ashley Blair went into labor on a packed Delta flight from Atlanta to Portland. Two off-duty EMTs on the plane delivered baby Brielle Renee just before landing — using a shoelace as a tourniquet for an IV. Mother and baby were healthy on arrival.
|
|
29
|
+
|
|
30
|
+
10. **UK inquiry warns Aukus submarine plan at risk**
|
|
31
|
+
A detailed House of Commons defence committee report finds UK submarine funding has "cracks already beginning to show," with chronic under-investment in shipbuilding and only one submarine yard (Barrow-in-Furness) already behind schedule. Australia has committed A$4.6 billion to help, but the committee warns political drift could derail the entire program.
|
|
32
|
+
<prompt>how many articles are there?</prompt>
|
|
33
|
+
<reasoning>The user is asking about the number of articles. From my previous analysis, there are 10 posts in the magazine, but only 5 unique articles (the rest are duplicates). Let me answer based on what I already know.</reasoning>
|
|
34
|
+
There are **10 posts** in the magazine, but only **5 unique articles** — each article appears twice (as duplicates from the two feeds).
|
|
35
|
+
<prompt>say your name inside an xml tag</prompt>
|
|
36
|
+
<name>Kai</name>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<prompt>summarize the posts</prompt>
|
|
2
|
+
<reasoning>The user wants me to summarize the posts related to the magazine in context. Let me first load the magazine object to understand its structure, and then list the candidate posts.</reasoning>
|
|
3
|
+
<status>Loading the magazine and listing candidate posts…</status>
|
|
4
|
+
<toolCall id="toolu_01WMMcsaHxTvuGxcMh2CkfL4" />
|
|
5
|
+
<toolCall id="toolu_01CxWNvXZ4jExfLEJumfMzqm" />
|
|
6
|
+
<reasoning>The magazine has 10 posts already curated, and there are no uncurated candidate posts. The user wants me to summarize the posts that are already in the magazine. Let me load them.</reasoning>
|
|
7
|
+
<status>No uncurated candidates — loading the 10 posts already in the magazine…</status>
|
|
8
|
+
<toolCall id="toolu_0152ftz33GL5M1DDi8GGDHi2" />
|
|
9
|
+
<reasoning>The magazine has 10 posts, but several are duplicates. Let me deduplicate by title/guid and summarize the unique articles. Unique articles:
|
|
10
|
+
1. "FBI affidavit quotes White House press dinner shooting suspect expressing rage at 'a pedophile, rapist and traitor' – US politics live" - About Cole Allen's manifesto and charges, plus King Charles visiting Trump at the White House.
|
|
11
|
+
2. "Australia news live: UK inquiry says 'cracks already beginning to show' on Aukus; search for missing five-year-old near Alice Springs grows" - Live blog covering Aukus inquiry, David Brat nominated as ambassador to Australia, fuel reserve crisis.
|
|
12
|
+
3. "Rebel Wilson gives evidence in high-profile defamation case against star of directorial debut" - Rebel Wilson testifying in defamation case brought by Charlotte MacInnes.
|
|
13
|
+
4. "Baby on board: US woman gives birth on Delta flight" - Ashley Blair delivered her baby aboard a Delta flight traveling from Atlanta to Portland.
|
|
14
|
+
5. "'Shortcomings and failures' could sink Aukus nuclear submarines plan, UK inquiry warns" - A UK House of Commons defence committee report identifies significant funding gaps threatening the Aukus submarine program.</reasoning>
|
|
15
|
+
Here's a summary of the **5 unique articles** currently in the magazine (some posts are duplicates):
|
|
16
|
+
|
|
17
|
+
1. **FBI affidavit quotes White House press dinner shooting suspect**
|
|
18
|
+
Federal charges filed against Cole Allen include excerpts from a manifesto he emailed to family and friends before attempting to charge into the White House Correspondents' Dinner. Separately, King Charles and Queen Camilla visited Donald Trump at the White House for tea and a beehive tour.
|
|
19
|
+
|
|
20
|
+
2. **Australia news live: Aukus 'cracks' & missing child search**
|
|
21
|
+
A UK House of Commons inquiry reveals "shortcomings and failings" in the Aukus submarine program. Also covered: David Brat nominated as the next US ambassador to Australia, and a push to extend Australia's fuel reserves from 30 to 60 days amid rising security concerns.
|
|
22
|
+
|
|
23
|
+
3. **Rebel Wilson testifies in defamation case**
|
|
24
|
+
Hollywood star Rebel Wilson gave evidence in a defamation lawsuit brought by Charlotte MacInnes, the lead actor of Wilson's directorial debut *The Deb*. The case centres on claims MacInnes confided to Wilson about being uncomfortable with a bathing request from a colleague.
|
|
25
|
+
|
|
26
|
+
4. **Baby born on Delta flight**
|
|
27
|
+
Passenger Ashley Blair went into labor on a packed Delta flight from Atlanta to Portland. Two off-duty EMTs on the plane delivered baby Brielle Renee just before landing — using a shoelace as a tourniquet for an IV. Mother and baby were healthy on arrival.
|
|
28
|
+
|
|
29
|
+
5. **UK inquiry warns Aukus submarine plan at risk**
|
|
30
|
+
A detailed House of Commons defence committee report finds UK submarine funding has "cracks already beginning to show," with chronic under-investment in shipbuilding and only one submarine yard (Barrow-in-Furness) already behind schedule. Australia has committed A$4.6 billion to help, but the committee warns political drift could derail the entire program.
|
|
31
|
+
<prompt>how many articles are there?</prompt>
|
|
32
|
+
<reasoning>The user is asking about the number of articles. From my previous analysis, there are 10 posts in the magazine, but only 5 unique articles (the rest are duplicates). Let me answer based on what I already know.</reasoning>
|
|
33
|
+
There are **10 posts** in the magazine, but only **5 unique articles** — each article appears twice (as duplicates from the two feeds).
|
|
34
|
+
<prompt>say your name inside an xml tag</prompt>
|
|
35
|
+
<name>Kai</name>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { trim } from '@dxos/util';
|
|
8
|
+
|
|
9
|
+
import { xmlElementLength } from './typewriter';
|
|
10
|
+
|
|
11
|
+
describe('typewriter', () => {
|
|
12
|
+
test('xmlElementLength handles hyphenated custom element names', ({ expect }) => {
|
|
13
|
+
const inner = 'Hello';
|
|
14
|
+
const el = `<dom-widget>${inner}</dom-widget>`;
|
|
15
|
+
expect(xmlElementLength(el)).toBe(el.length);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('xmlElementLength handle multi-line tags', ({ expect }) => {
|
|
19
|
+
const el = trim`
|
|
20
|
+
<summary>
|
|
21
|
+
Line 1
|
|
22
|
+
|
|
23
|
+
Line 2
|
|
24
|
+
</summary>
|
|
25
|
+
`;
|
|
26
|
+
expect(xmlElementLength(el)).toBe(el.length);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('xmlElementLength handles simple tag names', ({ expect }) => {
|
|
30
|
+
const el = '<prompt>Hi</prompt>';
|
|
31
|
+
expect(xmlElementLength(el)).toBe(el.length);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('xmlElementLength returns 0 until closing tag is complete', ({ expect }) => {
|
|
35
|
+
expect(xmlElementLength('<dom-widget>x')).toBe(0);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('xmlElementLength handles tags with blank lines in content', ({ expect }) => {
|
|
39
|
+
const el = trim`
|
|
40
|
+
<reasoning>
|
|
41
|
+
The user is asking me to think deeply about what markdown is.
|
|
42
|
+
|
|
43
|
+
But given the context of our conversation - we've been trying to scrape slab data from a website - I think they might be hinting at something specific.
|
|
44
|
+
</reasoning>
|
|
45
|
+
`;
|
|
46
|
+
expect(xmlElementLength(el)).toBe(el.length);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('xmlElementLength handles tags with multiple blank lines', ({ expect }) => {
|
|
50
|
+
const el = trim`
|
|
51
|
+
<reasoning>
|
|
52
|
+
First paragraph.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
Second paragraph after two blank lines.
|
|
56
|
+
</reasoning>
|
|
57
|
+
`;
|
|
58
|
+
expect(xmlElementLength(el)).toBe(el.length);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('xmlElementLength handles tags with only blank lines', ({ expect }) => {
|
|
62
|
+
const el = '<reasoning>\n\n\n</reasoning>';
|
|
63
|
+
expect(xmlElementLength(el)).toBe(el.length);
|
|
64
|
+
});
|
|
65
|
+
});
|