@agentshouse/mdruntime 0.1.0-c5fe3b2cddda7 → 0.1.0-c6197367d5fad
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 +21 -19
- package/dist/acceptance.d.ts +3 -0
- package/dist/acceptance.d.ts.map +1 -0
- package/dist/acceptance.js +299 -0
- package/dist/act-lanes.d.ts +30 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +225 -0
- package/dist/actions.d.ts +26 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +302 -0
- package/dist/adapter.d.ts +156 -89
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +3 -11
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +20 -60
- package/dist/authored.d.ts +88 -0
- package/dist/authored.d.ts.map +1 -0
- package/dist/authored.js +345 -0
- package/dist/bootstrap.d.ts +9 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +204 -85
- package/dist/cell.d.ts +6 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +9 -0
- package/dist/chain.d.ts +2 -1
- package/dist/chain.d.ts.map +1 -1
- package/dist/change-set.d.ts +4 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +6 -0
- package/dist/change.d.ts +5 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +7 -2
- package/dist/chat-types.d.ts +3 -0
- package/dist/chat-types.d.ts.map +1 -0
- package/dist/chat-types.js +11 -0
- package/dist/client.d.ts +33 -23
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +43 -56
- package/dist/collection.d.ts +26 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +19 -2
- package/dist/column.d.ts +5 -0
- package/dist/column.d.ts.map +1 -0
- package/dist/column.js +9 -0
- package/dist/compile.d.ts +8 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +286 -336
- package/dist/connection.d.ts +5 -142
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +111 -4993
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +7 -0
- package/dist/conversation-live.d.ts +150 -0
- package/dist/conversation-live.d.ts.map +1 -0
- package/dist/conversation-live.js +259 -0
- package/dist/conversation-row.d.ts +40 -0
- package/dist/conversation-row.d.ts.map +1 -0
- package/dist/conversation-row.js +66 -0
- package/dist/conversation.d.ts +72 -51
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +1001 -926
- package/dist/declaration.d.ts +10 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +24 -0
- package/dist/discovery.d.ts +11 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +157 -0
- package/dist/download.d.ts +6 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +42 -0
- package/dist/durability.d.ts +20 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +7 -0
- package/dist/entry.d.ts +2 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -8
- package/dist/expectation.d.ts +26 -13
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +72 -19
- package/dist/failure.d.ts +3 -0
- package/dist/failure.d.ts.map +1 -1
- package/dist/failure.js +6 -0
- package/dist/figures.d.ts +49 -0
- package/dist/figures.d.ts.map +1 -0
- package/dist/figures.js +199 -0
- package/dist/file.d.ts +1 -1
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +3 -2
- package/dist/holdings.d.ts +29 -0
- package/dist/holdings.d.ts.map +1 -0
- package/dist/holdings.js +95 -0
- package/dist/host.d.ts +21 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +83 -41
- package/dist/identity.d.ts +0 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -3
- package/dist/index.d.ts +37 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -5
- package/dist/install.d.ts +60 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +537 -0
- package/dist/lifecycle.d.ts +7 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +282 -0
- package/dist/listing.d.ts +52 -0
- package/dist/listing.d.ts.map +1 -0
- package/dist/listing.js +152 -0
- package/dist/live.d.ts +9 -6
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +118 -36
- package/dist/loaded.d.ts +5 -0
- package/dist/loaded.d.ts.map +1 -0
- package/dist/loaded.js +40 -0
- package/dist/locks.d.ts +7 -0
- package/dist/locks.d.ts.map +1 -0
- package/dist/locks.js +32 -0
- package/dist/lost.d.ts +5 -0
- package/dist/lost.d.ts.map +1 -0
- package/dist/lost.js +49 -0
- package/dist/media.d.ts +19 -2
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +105 -27
- package/dist/memory.d.ts +18 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +214 -91
- package/dist/messages.d.ts +35 -5
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +109 -39
- package/dist/model.d.ts +2 -10
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -14
- package/dist/models.d.ts +10 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +153 -0
- package/dist/observation.d.ts +28 -13
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +185 -81
- package/dist/opened.d.ts +1 -1
- package/dist/opened.d.ts.map +1 -1
- package/dist/opened.js +5 -5
- package/dist/opening.d.ts +4 -0
- package/dist/opening.d.ts.map +1 -0
- package/dist/opening.js +53 -0
- package/dist/outcome.d.ts +17 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +35 -2
- package/dist/overlay.d.ts +7 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +48 -24
- package/dist/page-metadata.d.ts +8 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +19 -0
- package/dist/parts.d.ts +4 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +13 -0
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +22 -0
- package/dist/preparation.d.ts +41 -0
- package/dist/preparation.d.ts.map +1 -0
- package/dist/preparation.js +314 -0
- package/dist/presence.d.ts +58 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +231 -0
- package/dist/queries.d.ts +16 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +308 -0
- package/dist/query.d.ts +14 -210
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -505
- package/dist/questions.d.ts +30 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +116 -0
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +480 -0
- package/dist/reach.d.ts +16 -15
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +257 -148
- package/dist/react.d.ts +19 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +33 -1
- package/dist/read.d.ts +7 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +17 -0
- package/dist/readiness.d.ts +9 -6
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +3 -5
- package/dist/reads.d.ts +39 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +178 -0
- package/dist/recovery.d.ts +3 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +38 -8
- package/dist/refresh.d.ts +2 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +31 -3
- package/dist/refusal.d.ts +5 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +55 -0
- package/dist/replica.d.ts +11 -16
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +66 -32
- package/dist/retried.d.ts +30 -0
- package/dist/retried.d.ts.map +1 -0
- package/dist/retried.js +72 -0
- package/dist/room-draft.d.ts +34 -10
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +331 -111
- package/dist/room-drafts.d.ts +24 -0
- package/dist/room-drafts.d.ts.map +1 -0
- package/dist/room-drafts.js +220 -0
- package/dist/room-list.d.ts +10 -0
- package/dist/room-list.d.ts.map +1 -0
- package/dist/room-list.js +45 -0
- package/dist/rows.d.ts +16 -22
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +49 -186
- package/dist/runtime.d.ts +34 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/save.d.ts +42 -86
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +332 -228
- package/dist/saves.d.ts +34 -0
- package/dist/saves.d.ts.map +1 -0
- package/dist/saves.js +437 -0
- package/dist/search.d.ts +12 -63
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +9 -52
- package/dist/seed.d.ts +11 -2
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +71 -1
- package/dist/shared.d.ts +1 -6
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +13 -95
- package/dist/shown.d.ts +35 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +313 -0
- package/dist/socket/admission.d.ts +7 -0
- package/dist/socket/admission.d.ts.map +1 -0
- package/dist/socket/admission.js +39 -0
- package/dist/socket/answers.d.ts +6 -0
- package/dist/socket/answers.d.ts.map +1 -0
- package/dist/socket/answers.js +20 -0
- package/dist/socket/lanes.d.ts +28 -0
- package/dist/socket/lanes.d.ts.map +1 -0
- package/dist/socket/lanes.js +103 -0
- package/dist/socket/reads.d.ts +10 -0
- package/dist/socket/reads.d.ts.map +1 -0
- package/dist/socket/reads.js +31 -0
- package/dist/socket/session.d.ts +38 -0
- package/dist/socket/session.d.ts.map +1 -0
- package/dist/socket/session.js +23 -0
- package/dist/socket.d.ts +67 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +164 -0
- package/dist/source.d.ts +59 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +93 -0
- package/dist/status.d.ts +0 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -6
- package/dist/store/installs.d.ts +30 -0
- package/dist/store/installs.d.ts.map +1 -0
- package/dist/store/installs.js +40 -0
- package/dist/store/readiness.d.ts +11 -0
- package/dist/store/readiness.d.ts.map +1 -0
- package/dist/store/readiness.js +68 -0
- package/dist/store/records.d.ts +224 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +466 -0
- package/dist/store/room-held.d.ts +8 -0
- package/dist/store/room-held.d.ts.map +1 -0
- package/dist/store/room-held.js +17 -0
- package/dist/store/rooms-shown.d.ts +8 -0
- package/dist/store/rooms-shown.d.ts.map +1 -0
- package/dist/store/rooms-shown.js +13 -0
- package/dist/store/space.d.ts +11 -0
- package/dist/store/space.d.ts.map +1 -0
- package/dist/store/space.js +41 -0
- package/dist/store/watchers.d.ts +17 -0
- package/dist/store/watchers.d.ts.map +1 -0
- package/dist/store/watchers.js +56 -0
- package/dist/store/writes.d.ts +24 -0
- package/dist/store/writes.d.ts.map +1 -0
- package/dist/store/writes.js +125 -0
- package/dist/store.d.ts +115 -143
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +171 -364
- package/dist/stored.d.ts +72 -35
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +337 -197
- package/dist/surface.d.ts +92 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +251 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +538 -0
- package/dist/tables.d.ts +118 -67
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +199 -278
- package/dist/tallies.d.ts +18 -0
- package/dist/tallies.d.ts.map +1 -0
- package/dist/tallies.js +128 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +9 -12
- package/dist/windows.d.ts +1 -12
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +2 -75
- package/dist/wire.d.ts +72 -9
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +26 -5
- package/package.json +3 -2
- package/dist/attempt.d.ts +0 -16
- package/dist/attempt.d.ts.map +0 -1
- package/dist/attempt.js +0 -70
- package/dist/fence.d.ts +0 -6
- package/dist/fence.d.ts.map +0 -1
- package/dist/fence.js +0 -10
- package/dist/fulltext.d.ts +0 -27
- package/dist/fulltext.d.ts.map +0 -1
- package/dist/fulltext.js +0 -370
- package/dist/log.d.ts +0 -5
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/words.d.ts +0 -19
- package/dist/words.d.ts.map +0 -1
- package/dist/words.js +0 -156
package/dist/live.js
CHANGED
|
@@ -1,50 +1,59 @@
|
|
|
1
|
-
import { changeOf, digestOf, } from './observation.js';
|
|
2
|
-
import {
|
|
1
|
+
import { changeOf, digestOf, keyedAt, keyedInto, samePending, unchanged, } from './observation.js';
|
|
2
|
+
import { uncaught } from './failure.js';
|
|
3
|
+
import { roomsOfReach } from './rows.js';
|
|
3
4
|
function narrowed(plan) {
|
|
4
5
|
return (plan.paths !== null &&
|
|
5
6
|
plan.hop === null &&
|
|
6
7
|
plan.backlinks === null &&
|
|
7
8
|
!(plan.shape.kind === 'documents' && plan.shape.backlinks));
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return (plan.reach.rooms.includes(locator) ||
|
|
17
|
-
plan.reach.documents.some((document) => roomOfKey(document) === locator) ||
|
|
18
|
-
plan.reach.areas.some((area) => area.room === locator && area.types.length > 0));
|
|
10
|
+
export function readerOf(plan) {
|
|
11
|
+
const locked = new Set(plan.locked);
|
|
12
|
+
const named = plan.rooms === null ? null : new Set(plan.rooms);
|
|
13
|
+
const reached = plan.reach === null ? null : roomsOfReach(plan.reach);
|
|
14
|
+
return (locator) => !locked.has(locator) &&
|
|
15
|
+
(named === null || named.has(locator)) &&
|
|
16
|
+
(reached === null || reached.has(locator));
|
|
19
17
|
}
|
|
20
|
-
function affected(plan, set) {
|
|
21
|
-
if (set.rooms.some(
|
|
18
|
+
function affected({ plan, reads }, set) {
|
|
19
|
+
if (set.rooms.some(reads))
|
|
22
20
|
return true;
|
|
23
21
|
const paths = narrowed(plan) ? new Set(plan.paths) : null;
|
|
24
|
-
return set.documents.some(({ locator, path }) => reads(
|
|
22
|
+
return set.documents.some(({ locator, path }) => reads(locator) && (paths === null || path === null || paths.has(path)));
|
|
25
23
|
}
|
|
26
|
-
function shown(entry) {
|
|
27
|
-
const cover = entry.cover();
|
|
24
|
+
function shown(entry, held) {
|
|
25
|
+
const cover = entry.cover(held);
|
|
28
26
|
return JSON.stringify('pending' in cover ? cover : cover.coverage);
|
|
29
27
|
}
|
|
30
|
-
export function createLiveQueries(run) {
|
|
28
|
+
export function createLiveQueries(run, holding) {
|
|
31
29
|
const entries = new Map();
|
|
32
30
|
let closed = false;
|
|
31
|
+
let recoveringNow = false;
|
|
32
|
+
let recoveringAll = false;
|
|
33
|
+
const recovering = new Set();
|
|
33
34
|
function deliver(entry, next) {
|
|
34
35
|
const previous = entry.digest;
|
|
35
36
|
entry.digest = digestOf(next);
|
|
37
|
+
entry.pending = 'pending' in entry.digest ? entry.digest.pending : null;
|
|
36
38
|
entry.covered = JSON.stringify('pending' in next.result ? next.result : next.result.coverage);
|
|
37
39
|
const change = previous === undefined ? null : changeOf(previous, next);
|
|
38
40
|
if (change !== null) {
|
|
39
41
|
for (const listener of entry.ready)
|
|
40
42
|
listener(change);
|
|
41
43
|
}
|
|
42
|
-
for (const listener of entry.fresh) {
|
|
44
|
+
for (const listener of entry.fresh.keys()) {
|
|
43
45
|
entry.ready.add(listener);
|
|
44
46
|
listener(next);
|
|
45
47
|
}
|
|
46
48
|
entry.fresh.clear();
|
|
47
49
|
}
|
|
50
|
+
async function delivered(entry) {
|
|
51
|
+
const { current, ...next } = await run(entry.plan, async () => entry.cover(await holding()));
|
|
52
|
+
if (closed || entry.listeners.size === 0)
|
|
53
|
+
return null;
|
|
54
|
+
deliver(entry, next);
|
|
55
|
+
return current;
|
|
56
|
+
}
|
|
48
57
|
function schedule(entry) {
|
|
49
58
|
if (closed || entry.listeners.size === 0)
|
|
50
59
|
return;
|
|
@@ -57,47 +66,120 @@ export function createLiveQueries(run) {
|
|
|
57
66
|
try {
|
|
58
67
|
for (;;) {
|
|
59
68
|
entry.dirty = false;
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
69
|
+
const current = await delivered(entry);
|
|
70
|
+
if (current === null)
|
|
62
71
|
return;
|
|
63
|
-
|
|
64
|
-
if (
|
|
72
|
+
const held = await holding();
|
|
73
|
+
if (entry.fresh.size > 0 || (entry.dirty && !current()))
|
|
74
|
+
continue;
|
|
75
|
+
if (shown(entry, held) === entry.covered)
|
|
65
76
|
break;
|
|
66
77
|
}
|
|
67
78
|
}
|
|
68
|
-
catch {
|
|
69
|
-
|
|
79
|
+
catch (error) {
|
|
80
|
+
const unanswered = [...entry.fresh.values()];
|
|
81
|
+
entry.fresh.clear();
|
|
82
|
+
for (const failed of unanswered)
|
|
83
|
+
failed(error);
|
|
70
84
|
}
|
|
71
85
|
finally {
|
|
72
86
|
entry.running = false;
|
|
73
87
|
}
|
|
74
88
|
})();
|
|
75
89
|
}
|
|
90
|
+
function pendingMoved(entry, held, rooms) {
|
|
91
|
+
const { pending } = entry;
|
|
92
|
+
if (pending === null || pending.size === 0 || entry.running || entry.fresh.size > 0) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const at = entry.pendingAt(held, rooms);
|
|
96
|
+
const change = at === null ? null : keyedAt(pending, at, samePending);
|
|
97
|
+
if (change === null || change.removed.length === pending.size)
|
|
98
|
+
return false;
|
|
99
|
+
keyedInto(pending, change);
|
|
100
|
+
entry.covered = '';
|
|
101
|
+
if (unchanged(change))
|
|
102
|
+
return true;
|
|
103
|
+
for (const listener of entry.ready)
|
|
104
|
+
listener({ pending: change });
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
function recovered(locators) {
|
|
108
|
+
if (locators === undefined)
|
|
109
|
+
recoveringAll = true;
|
|
110
|
+
else
|
|
111
|
+
for (const locator of locators)
|
|
112
|
+
recovering.add(locator);
|
|
113
|
+
if (recoveringNow)
|
|
114
|
+
return;
|
|
115
|
+
recoveringNow = true;
|
|
116
|
+
void (async () => {
|
|
117
|
+
try {
|
|
118
|
+
while ((recoveringAll || recovering.size > 0) && !closed) {
|
|
119
|
+
const all = recoveringAll;
|
|
120
|
+
const touched = [...recovering];
|
|
121
|
+
recoveringAll = false;
|
|
122
|
+
recovering.clear();
|
|
123
|
+
const reached = [...entries.values()].filter((entry) => all || touched.some(entry.reads));
|
|
124
|
+
for (const entry of reached) {
|
|
125
|
+
if (entry.running)
|
|
126
|
+
entry.dirty = true;
|
|
127
|
+
}
|
|
128
|
+
const waiting = reached.filter((entry) => !entry.running);
|
|
129
|
+
if (waiting.length === 0)
|
|
130
|
+
continue;
|
|
131
|
+
const held = await holding();
|
|
132
|
+
for (const entry of waiting) {
|
|
133
|
+
if (entry.running)
|
|
134
|
+
continue;
|
|
135
|
+
const read = all ? [] : touched.filter(entry.reads);
|
|
136
|
+
if (read.length > 0 && pendingMoved(entry, held, read))
|
|
137
|
+
continue;
|
|
138
|
+
if (entry.digest === undefined || shown(entry, held) !== entry.covered)
|
|
139
|
+
schedule(entry);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
uncaught(error);
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
recoveringNow = false;
|
|
148
|
+
}
|
|
149
|
+
})();
|
|
150
|
+
}
|
|
76
151
|
return {
|
|
77
152
|
touched(set) {
|
|
153
|
+
const pending = new Set();
|
|
78
154
|
for (const entry of entries.values()) {
|
|
79
|
-
if (affected(entry
|
|
80
|
-
schedule(entry);
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
recover() {
|
|
84
|
-
for (const entry of entries.values()) {
|
|
85
|
-
if (entry.running)
|
|
155
|
+
if (!affected(entry, set))
|
|
86
156
|
continue;
|
|
87
|
-
if (entry.
|
|
157
|
+
if (entry.pending === null || entry.running) {
|
|
88
158
|
schedule(entry);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
for (const locator of set.rooms)
|
|
162
|
+
pending.add(locator);
|
|
163
|
+
for (const { locator } of set.documents)
|
|
164
|
+
pending.add(locator);
|
|
89
165
|
}
|
|
166
|
+
if (pending.size > 0)
|
|
167
|
+
recovered([...pending]);
|
|
90
168
|
},
|
|
91
|
-
|
|
169
|
+
recover: recovered,
|
|
170
|
+
watch(plan, identity, cover, pendingAt, listener, failed) {
|
|
92
171
|
let entry = entries.get(identity);
|
|
93
172
|
if (entry === undefined) {
|
|
94
173
|
entry = {
|
|
95
174
|
plan,
|
|
175
|
+
reads: readerOf(plan),
|
|
96
176
|
cover,
|
|
177
|
+
pendingAt,
|
|
97
178
|
listeners: new Set(),
|
|
98
|
-
fresh: new
|
|
179
|
+
fresh: new Map(),
|
|
99
180
|
ready: new Set(),
|
|
100
181
|
digest: undefined,
|
|
182
|
+
pending: null,
|
|
101
183
|
covered: '',
|
|
102
184
|
dirty: false,
|
|
103
185
|
running: false,
|
|
@@ -106,7 +188,7 @@ export function createLiveQueries(run) {
|
|
|
106
188
|
}
|
|
107
189
|
const held = entry;
|
|
108
190
|
held.listeners.add(listener);
|
|
109
|
-
held.fresh.
|
|
191
|
+
held.fresh.set(listener, failed);
|
|
110
192
|
schedule(held);
|
|
111
193
|
return () => {
|
|
112
194
|
held.listeners.delete(listener);
|
package/dist/loaded.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BuildFile } from './client.js';
|
|
2
|
+
export declare function parsed(file: Blob | null): Promise<unknown>;
|
|
3
|
+
export declare function perBuild<T>(buildFile: BuildFile, key: string, make: () => Promise<T>): Promise<T>;
|
|
4
|
+
export declare function loaded<T>(buildFile: BuildFile, name: string, read?: (file: Blob | null) => Promise<unknown>): Promise<T | null>;
|
|
5
|
+
//# sourceMappingURL=loaded.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loaded.d.ts","sourceRoot":"","sources":["../src/loaded.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAc7C,wBAAsB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAYjG;AAED,wBAAgB,MAAM,CAAC,CAAC,EACtB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,CAAY,GACvD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAEnB"}
|
package/dist/loaded.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
const holdings = new WeakMap();
|
|
10
|
+
async function imported(file) {
|
|
11
|
+
if (file === null)
|
|
12
|
+
return null;
|
|
13
|
+
const address = URL.createObjectURL(file);
|
|
14
|
+
try {
|
|
15
|
+
return await import(__rewriteRelativeImportExtension(address));
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
URL.revokeObjectURL(address);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function parsed(file) {
|
|
22
|
+
return file === null ? null : JSON.parse(await file.text());
|
|
23
|
+
}
|
|
24
|
+
export function perBuild(buildFile, key, make) {
|
|
25
|
+
let named = holdings.get(buildFile);
|
|
26
|
+
if (named === undefined) {
|
|
27
|
+
named = new Map();
|
|
28
|
+
holdings.set(buildFile, named);
|
|
29
|
+
}
|
|
30
|
+
const holding = named.get(key);
|
|
31
|
+
if (holding !== undefined)
|
|
32
|
+
return holding;
|
|
33
|
+
const making = make();
|
|
34
|
+
named.set(key, making);
|
|
35
|
+
making.catch(() => named.delete(key));
|
|
36
|
+
return making;
|
|
37
|
+
}
|
|
38
|
+
export function loaded(buildFile, name, read = imported) {
|
|
39
|
+
return perBuild(buildFile, name, () => buildFile(name).then(read));
|
|
40
|
+
}
|
package/dist/locks.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Runtime } from './runtime.js';
|
|
2
|
+
export declare function locked({ store, presence }: Runtime, locator: string): Promise<boolean>;
|
|
3
|
+
export declare function lockedRooms({ store, presence }: Runtime): Promise<readonly string[]>;
|
|
4
|
+
export declare function relocked(runtime: Runtime, before: readonly string[]): Promise<void>;
|
|
5
|
+
export declare function connectionLost(runtime: Runtime): void;
|
|
6
|
+
export declare function watchLocks({ store }: Runtime, notify: () => void): () => void;
|
|
7
|
+
//# sourceMappingURL=locks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../src/locks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,wBAAsB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5F;AAED,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAG1F;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,iBAKzE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,QAU9C;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAE7E"}
|
package/dist/locks.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { uncaught } from './failure.js';
|
|
2
|
+
import { emitRooms, LOCKS_TOPIC } from './shown.js';
|
|
3
|
+
export async function locked({ store, presence }, locator) {
|
|
4
|
+
return presence.locked(locator, async () => (await store.open()).offline(locator));
|
|
5
|
+
}
|
|
6
|
+
export async function lockedRooms({ store, presence }) {
|
|
7
|
+
const { rooms, locking } = await store.covering();
|
|
8
|
+
return presence.lockedAmong(rooms, locking);
|
|
9
|
+
}
|
|
10
|
+
export async function relocked(runtime, before) {
|
|
11
|
+
const after = await lockedRooms(runtime);
|
|
12
|
+
if (JSON.stringify(after) === JSON.stringify(before))
|
|
13
|
+
return;
|
|
14
|
+
emitRooms(runtime);
|
|
15
|
+
runtime.store.tell(LOCKS_TOPIC, undefined);
|
|
16
|
+
}
|
|
17
|
+
export function connectionLost(runtime) {
|
|
18
|
+
const { socket, presence } = runtime;
|
|
19
|
+
if (socket.closed())
|
|
20
|
+
return;
|
|
21
|
+
presence.connectionLost(() => {
|
|
22
|
+
if (socket.isOpen() || socket.closed())
|
|
23
|
+
return;
|
|
24
|
+
void lockedRooms(runtime).then((before) => {
|
|
25
|
+
presence.lapse();
|
|
26
|
+
return relocked(runtime, before);
|
|
27
|
+
}, uncaught);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function watchLocks({ store }, notify) {
|
|
31
|
+
return store.watch(LOCKS_TOPIC, notify).stop;
|
|
32
|
+
}
|
package/dist/lost.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Runtime } from './runtime.js';
|
|
2
|
+
export declare function eraseFenced({ store }: Runtime, locators: readonly string[]): Promise<void>;
|
|
3
|
+
export declare function fenceLive(runtime: Runtime, locators: readonly string[]): void;
|
|
4
|
+
export declare function loseRooms(runtime: Runtime, locators: readonly string[]): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=lost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lost.d.ts","sourceRoot":"","sources":["../src/lost.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAK5C,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,iBAIhF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,QAMtE;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,iBA+B5E"}
|
package/dist/lost.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { changeSet, mergeChangeSets } from './change-set.js';
|
|
2
|
+
import { ERASE_BATCH } from './install.js';
|
|
3
|
+
import { unpair } from './queue.js';
|
|
4
|
+
import { recoverReads } from './shown.js';
|
|
5
|
+
import { yielded } from './turn.js';
|
|
6
|
+
export async function eraseFenced({ store }, locators) {
|
|
7
|
+
for (const locator of locators) {
|
|
8
|
+
while (await store.durably((local) => local.erase(locator, ERASE_BATCH)))
|
|
9
|
+
await yielded();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function fenceLive(runtime, locators) {
|
|
13
|
+
const { store, socket, presence } = runtime;
|
|
14
|
+
for (const locator of new Set(locators)) {
|
|
15
|
+
if (!presence.lose(locator, socket.session.now().discoveries))
|
|
16
|
+
continue;
|
|
17
|
+
store.forget(locator);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function loseRooms(runtime, locators) {
|
|
21
|
+
const { store, presence } = runtime;
|
|
22
|
+
fenceLive(runtime, locators);
|
|
23
|
+
const fresh = [...new Set(locators)].filter((locator) => presence.writing(locator));
|
|
24
|
+
if (fresh.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
let held = [];
|
|
27
|
+
try {
|
|
28
|
+
await store.durably(async (local) => {
|
|
29
|
+
held = await local.roomDrafts();
|
|
30
|
+
await local.fence(fresh);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
for (const locator of fresh)
|
|
35
|
+
presence.unwritten(locator);
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
store.changed(mergeChangeSets(fresh.map((locator) => changeSet(locator, {
|
|
40
|
+
documents: null,
|
|
41
|
+
room: true,
|
|
42
|
+
queue: true,
|
|
43
|
+
drafts: held.filter((draft) => draft.locator === locator).map(({ path }) => path),
|
|
44
|
+
}))));
|
|
45
|
+
recoverReads(runtime, fresh);
|
|
46
|
+
}
|
|
47
|
+
await unpair(runtime);
|
|
48
|
+
await eraseFenced(runtime, fresh);
|
|
49
|
+
}
|
package/dist/media.d.ts
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import type { MdRuntimeClient } from './client.js';
|
|
2
|
-
import { type ShownAnswer } from './outcome.js';
|
|
2
|
+
import { type DownloadAnswer, type ShownAnswer } from './outcome.js';
|
|
3
3
|
export declare const ROOM_MEDIA = "room-media";
|
|
4
|
+
export declare const KEYED_MEDIA = "ahc-attachment";
|
|
5
|
+
export declare const MEDIA = "room-media, ahc-attachment";
|
|
6
|
+
export declare const DIAGRAM = "md-diagram";
|
|
7
|
+
export declare const VIEWING = "ahc-viewer";
|
|
4
8
|
type Show = (room: string, path: string, revision?: string) => Promise<ShownAnswer>;
|
|
9
|
+
export type MediaAt = {
|
|
10
|
+
readonly link: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly room: string;
|
|
13
|
+
readonly path: string;
|
|
14
|
+
readonly revision: string | undefined;
|
|
15
|
+
};
|
|
5
16
|
export declare function shownBy(show: Show, client: MdRuntimeClient): MdRuntimeClient;
|
|
6
|
-
export declare function
|
|
17
|
+
export declare function mediaAt(media: Element): MediaAt | null;
|
|
18
|
+
export declare function mediaTag(at: MediaAt): string;
|
|
19
|
+
export declare function downloadAt(client: MdRuntimeClient, at: MediaAt): Promise<DownloadAnswer>;
|
|
20
|
+
export declare function rendered(element: Element): boolean;
|
|
21
|
+
export declare function viewable(element: Element): boolean;
|
|
22
|
+
export declare function viewFile(client: MdRuntimeClient, media: Element): void;
|
|
23
|
+
export declare function defineRoomMedia(client: Promise<MdRuntimeClient> | MdRuntimeClient): void;
|
|
7
24
|
export {};
|
|
8
25
|
//# sourceMappingURL=media.d.ts.map
|
package/dist/media.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAExF,eAAO,MAAM,UAAU,eAAe,CAAC;AAEvC,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAE5C,eAAO,MAAM,KAAK,+BAAkC,CAAC;AAMrD,eAAO,MAAM,OAAO,eAAe,CAAC;AAEpC,eAAO,MAAM,OAAO,eAAe,CAAC;AAgCpC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAEpF,MAAM,MAAM,OAAO,GACf;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAI5F,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,GAAG,eAAe,CAG5E;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAUtD;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAE5C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAIxF;AA6BD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAElD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAMlD;AA4BD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAEtE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,GAAG,IAAI,CAgMxF"}
|
package/dist/media.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isAudioType, isImageType, isVideoType } from '@agentshouse/mdmodel';
|
|
2
|
+
import { loaded } from './loaded.js';
|
|
3
|
+
import { downloadAttachment } from './download.js';
|
|
4
|
+
import { blobOf, UNCERTAIN } from './outcome.js';
|
|
2
5
|
export const ROOM_MEDIA = 'room-media';
|
|
6
|
+
export const KEYED_MEDIA = 'ahc-attachment';
|
|
7
|
+
export const MEDIA = `${ROOM_MEDIA}, ${KEYED_MEDIA}`;
|
|
8
|
+
const VIEWER = 'viewer';
|
|
9
|
+
const RENDERED = '.ahc, .ahc-markdown';
|
|
10
|
+
export const DIAGRAM = 'md-diagram';
|
|
11
|
+
export const VIEWING = 'ahc-viewer';
|
|
12
|
+
const PRESSED_ELSEWHERE = 'a[href], button, input, select, textarea, summary, label, [role="button"], [role="link"]';
|
|
3
13
|
const ATTRIBUTES = ['room', 'path', 'revision', 'width', 'height', 'alt'];
|
|
4
|
-
const
|
|
14
|
+
const KEYED_ATTRIBUTES = ['link', 'alt'];
|
|
15
|
+
const LOADING = new Set(['link', 'room', 'path', 'revision']);
|
|
5
16
|
const NEARING = '600px 0px';
|
|
6
17
|
const RELINKS = 2;
|
|
7
18
|
// The Room's stream brings a file seconds after the text that links it, minutes after on a first open, and a page's reach of its Rooms settles seconds after it opens, so a file not shown yet is asked for again every three seconds.
|
|
@@ -10,12 +21,42 @@ const SHAPE = '16 / 9';
|
|
|
10
21
|
const STYLE = `:host{display:block}
|
|
11
22
|
[part=box]{position:relative;overflow:hidden}
|
|
12
23
|
[part=box]>img,[part=box]>video,[part=box]>audio{display:block;width:100%;height:100%;object-fit:contain}
|
|
13
|
-
[part=box]>
|
|
24
|
+
[part=box]>video:not([controls]){cursor:pointer}
|
|
25
|
+
[part=box]>slot{display:flex;align-items:center;justify-content:center;width:100%;height:100%;text-align:center}
|
|
26
|
+
[part=play]{position:absolute;top:50%;left:50%;width:56px;height:56px;margin:-28px 0 0 -28px;border-radius:50%;background:rgb(0 0 0/.6);pointer-events:none}
|
|
27
|
+
[part=play]::before{content:"";position:absolute;top:18px;left:22px;border-style:solid;border-width:10px 0 10px 16px;border-color:transparent transparent transparent #fff}`;
|
|
14
28
|
const shows = new WeakMap();
|
|
15
29
|
export function shownBy(show, client) {
|
|
16
30
|
shows.set(client, show);
|
|
17
31
|
return client;
|
|
18
32
|
}
|
|
33
|
+
export function mediaAt(media) {
|
|
34
|
+
if (media.localName === KEYED_MEDIA) {
|
|
35
|
+
const link = media.getAttribute('link');
|
|
36
|
+
return link === null ? null : { link };
|
|
37
|
+
}
|
|
38
|
+
const room = media.getAttribute('room');
|
|
39
|
+
const path = media.getAttribute('path');
|
|
40
|
+
return room === null || path === null
|
|
41
|
+
? null
|
|
42
|
+
: { room, path, revision: media.getAttribute('revision') ?? undefined };
|
|
43
|
+
}
|
|
44
|
+
export function mediaTag(at) {
|
|
45
|
+
return 'link' in at ? KEYED_MEDIA : ROOM_MEDIA;
|
|
46
|
+
}
|
|
47
|
+
export function downloadAt(client, at) {
|
|
48
|
+
return 'link' in at
|
|
49
|
+
? downloadAttachment(client, at.link)
|
|
50
|
+
: client.binaryFile.download(at.room, at.path, at.revision);
|
|
51
|
+
}
|
|
52
|
+
function shownAt(client, at) {
|
|
53
|
+
if (at === null)
|
|
54
|
+
return null;
|
|
55
|
+
if ('link' in at)
|
|
56
|
+
return client.conversation.attachment(at.link);
|
|
57
|
+
const show = shows.get(client);
|
|
58
|
+
return show === undefined ? null : show(at.room, at.path, at.revision);
|
|
59
|
+
}
|
|
19
60
|
function ratioOf(width, height) {
|
|
20
61
|
const across = Number(width);
|
|
21
62
|
const down = Number(height);
|
|
@@ -29,23 +70,62 @@ function refusedForGood(shown) {
|
|
|
29
70
|
return (shown.kind === 'rejected' || shown.kind === 'scoped-refusal') && !shown.retryable;
|
|
30
71
|
}
|
|
31
72
|
function drawnFor(mediaType) {
|
|
32
|
-
if (mediaType
|
|
73
|
+
if (isImageType(mediaType))
|
|
33
74
|
return 'img';
|
|
34
|
-
if (mediaType
|
|
75
|
+
if (isVideoType(mediaType))
|
|
35
76
|
return 'video';
|
|
36
|
-
if (mediaType
|
|
77
|
+
if (isAudioType(mediaType))
|
|
37
78
|
return 'audio';
|
|
38
79
|
return null;
|
|
39
80
|
}
|
|
40
|
-
export function
|
|
41
|
-
|
|
81
|
+
export function rendered(element) {
|
|
82
|
+
return element.closest(RENDERED) !== null;
|
|
83
|
+
}
|
|
84
|
+
export function viewable(element) {
|
|
85
|
+
if (element.localName === 'figure')
|
|
86
|
+
return element.classList.contains(DIAGRAM);
|
|
87
|
+
if (!element.matches(MEDIA) || element.closest(`.${VIEWING}`) !== null)
|
|
88
|
+
return false;
|
|
89
|
+
return (rendered(element) || (element.shadowRoot?.querySelector('[part=box] > video') ?? null) !== null);
|
|
90
|
+
}
|
|
91
|
+
function viewed(client, opener, alone) {
|
|
92
|
+
void loaded(client.buildFile, VIEWER).then((file) => file?.openViewer({
|
|
93
|
+
opener,
|
|
94
|
+
alone,
|
|
95
|
+
download: (at) => void downloadAt(client, at),
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
function pressed(client) {
|
|
99
|
+
return (event) => {
|
|
100
|
+
if (event.defaultPrevented || event.detail > 1)
|
|
101
|
+
return;
|
|
102
|
+
for (const node of event.composedPath()) {
|
|
103
|
+
if (!(node instanceof Element))
|
|
104
|
+
continue;
|
|
105
|
+
if (viewable(node)) {
|
|
106
|
+
event.preventDefault();
|
|
107
|
+
void client.then((one) => viewed(one, node, !rendered(node)));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (node.matches(PRESSED_ELSEWHERE))
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export function viewFile(client, media) {
|
|
116
|
+
viewed(client, media, true);
|
|
117
|
+
}
|
|
118
|
+
export function defineRoomMedia(client) {
|
|
119
|
+
if (customElements.get(ROOM_MEDIA) !== undefined)
|
|
42
120
|
return;
|
|
43
121
|
const connected = Promise.resolve(client);
|
|
122
|
+
document.addEventListener('click', pressed(connected));
|
|
44
123
|
class RoomMedia extends HTMLElement {
|
|
45
124
|
static observedAttributes = ATTRIBUTES;
|
|
46
125
|
#root = this.attachShadow({ mode: 'open' });
|
|
47
126
|
#box = document.createElement('div');
|
|
48
127
|
#fallback = document.createElement('slot');
|
|
128
|
+
#play = document.createElement('span');
|
|
49
129
|
#watching = null;
|
|
50
130
|
#near = false;
|
|
51
131
|
#asked = 0;
|
|
@@ -56,6 +136,7 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
56
136
|
constructor() {
|
|
57
137
|
super();
|
|
58
138
|
this.#box.setAttribute('part', 'box');
|
|
139
|
+
this.#play.setAttribute('part', 'play');
|
|
59
140
|
this.#root.append(Object.assign(document.createElement('style'), { textContent: STYLE }), this.#box);
|
|
60
141
|
this.#shape();
|
|
61
142
|
}
|
|
@@ -107,15 +188,8 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
107
188
|
async #load() {
|
|
108
189
|
const asked = (this.#asked += 1);
|
|
109
190
|
this.#loaded = false;
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const revision = this.getAttribute('revision') ?? undefined;
|
|
113
|
-
if (room === null || path === null) {
|
|
114
|
-
this.#unreadable();
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const show = shows.get(await connected);
|
|
118
|
-
const shown = show === undefined ? null : await show(room, path, revision).catch(() => UNCERTAIN);
|
|
191
|
+
const showing = shownAt(await connected, mediaAt(this));
|
|
192
|
+
const shown = showing === null ? null : await showing.catch(() => UNCERTAIN);
|
|
119
193
|
if (asked !== this.#asked)
|
|
120
194
|
return;
|
|
121
195
|
if (shown?.kind === 'link') {
|
|
@@ -129,11 +203,7 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
129
203
|
this.#unshown(asked);
|
|
130
204
|
return;
|
|
131
205
|
}
|
|
132
|
-
const copy = await
|
|
133
|
-
headers: { 'content-type': shown.mediaType },
|
|
134
|
-
})
|
|
135
|
-
.blob()
|
|
136
|
-
.catch(() => null);
|
|
206
|
+
const copy = await blobOf(shown).catch(() => null);
|
|
137
207
|
if (asked !== this.#asked)
|
|
138
208
|
return;
|
|
139
209
|
if (copy === null)
|
|
@@ -157,7 +227,9 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
157
227
|
if (content === null)
|
|
158
228
|
this.#box.replaceChildren();
|
|
159
229
|
else if (content.parentNode !== this.#box)
|
|
160
|
-
this.#box.replaceChildren(content
|
|
230
|
+
this.#box.replaceChildren(...(content instanceof HTMLVideoElement && !content.controls
|
|
231
|
+
? [content, this.#play]
|
|
232
|
+
: [content]));
|
|
161
233
|
this.#label();
|
|
162
234
|
}
|
|
163
235
|
#unreadable() {
|
|
@@ -174,13 +246,16 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
174
246
|
const kept = this.#drawn?.localName === tag ? this.#drawn : null;
|
|
175
247
|
const drawn = kept ?? document.createElement(tag);
|
|
176
248
|
if (kept === null) {
|
|
249
|
+
const plays = !(drawn instanceof HTMLVideoElement) || this.closest(`.${VIEWING}`) !== null;
|
|
177
250
|
if (drawn instanceof HTMLImageElement)
|
|
178
251
|
drawn.decoding = 'async';
|
|
179
252
|
if (drawn instanceof HTMLMediaElement) {
|
|
180
|
-
drawn.controls = true;
|
|
181
253
|
drawn.preload = 'metadata';
|
|
182
|
-
|
|
183
|
-
|
|
254
|
+
drawn.controls = plays;
|
|
255
|
+
}
|
|
256
|
+
if (drawn instanceof HTMLVideoElement && plays) {
|
|
257
|
+
drawn.autoplay = true;
|
|
258
|
+
drawn.setAttribute('playsinline', '');
|
|
184
259
|
}
|
|
185
260
|
drawn.addEventListener(drawn instanceof HTMLImageElement ? 'load' : 'loadedmetadata', () => {
|
|
186
261
|
if (drawn !== this.#drawn)
|
|
@@ -214,5 +289,8 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
214
289
|
void this.#load();
|
|
215
290
|
}
|
|
216
291
|
}
|
|
217
|
-
|
|
292
|
+
customElements.define(ROOM_MEDIA, RoomMedia);
|
|
293
|
+
customElements.define(KEYED_MEDIA, class extends RoomMedia {
|
|
294
|
+
static observedAttributes = KEYED_ATTRIBUTES;
|
|
295
|
+
});
|
|
218
296
|
}
|