@brass-build/client 0.1.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/AGENTS.md +255 -0
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +836 -0
- package/dist/api-fetch.d.ts +16 -0
- package/dist/api-fetch.d.ts.map +1 -0
- package/dist/api-fetch.js +97 -0
- package/dist/api-fetch.js.map +1 -0
- package/dist/api-headers.d.ts +3 -0
- package/dist/api-headers.d.ts.map +1 -0
- package/dist/api-headers.js +25 -0
- package/dist/api-headers.js.map +1 -0
- package/dist/auth-flow.d.ts +23 -0
- package/dist/auth-flow.d.ts.map +1 -0
- package/dist/auth-flow.js +76 -0
- package/dist/auth-flow.js.map +1 -0
- package/dist/client.d.ts +106 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1278 -0
- package/dist/client.js.map +1 -0
- package/dist/doc-url-sync.d.ts +19 -0
- package/dist/doc-url-sync.d.ts.map +1 -0
- package/dist/doc-url-sync.js +181 -0
- package/dist/doc-url-sync.js.map +1 -0
- package/dist/document-branches.d.ts +32 -0
- package/dist/document-branches.d.ts.map +1 -0
- package/dist/document-branches.js +89 -0
- package/dist/document-branches.js.map +1 -0
- package/dist/document-checkpoints.d.ts +24 -0
- package/dist/document-checkpoints.d.ts.map +1 -0
- package/dist/document-checkpoints.js +115 -0
- package/dist/document-checkpoints.js.map +1 -0
- package/dist/document-commands.d.ts +93 -0
- package/dist/document-commands.d.ts.map +1 -0
- package/dist/document-commands.js +423 -0
- package/dist/document-commands.js.map +1 -0
- package/dist/document-signals.d.ts +53 -0
- package/dist/document-signals.d.ts.map +1 -0
- package/dist/document-signals.js +114 -0
- package/dist/document-signals.js.map +1 -0
- package/dist/document-streams.d.ts +22 -0
- package/dist/document-streams.d.ts.map +1 -0
- package/dist/document-streams.js +98 -0
- package/dist/document-streams.js.map +1 -0
- package/dist/document-thumbnail-capture.d.ts +27 -0
- package/dist/document-thumbnail-capture.d.ts.map +1 -0
- package/dist/document-thumbnail-capture.js +160 -0
- package/dist/document-thumbnail-capture.js.map +1 -0
- package/dist/documents-namespace.d.ts +134 -0
- package/dist/documents-namespace.d.ts.map +1 -0
- package/dist/documents-namespace.js +190 -0
- package/dist/documents-namespace.js.map +1 -0
- package/dist/documents.d.ts +146 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +2045 -0
- package/dist/documents.js.map +1 -0
- package/dist/emitter.d.ts +15 -0
- package/dist/emitter.d.ts.map +1 -0
- package/dist/emitter.js +90 -0
- package/dist/emitter.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +22 -0
- package/dist/errors.js.map +1 -0
- package/dist/export-guest.d.ts +9 -0
- package/dist/export-guest.d.ts.map +1 -0
- package/dist/export-guest.js +225 -0
- package/dist/export-guest.js.map +1 -0
- package/dist/fetch-retry.d.ts +16 -0
- package/dist/fetch-retry.d.ts.map +1 -0
- package/dist/fetch-retry.js +90 -0
- package/dist/fetch-retry.js.map +1 -0
- package/dist/guest-link.d.ts +3 -0
- package/dist/guest-link.d.ts.map +1 -0
- package/dist/guest-link.js +13 -0
- package/dist/guest-link.js.map +1 -0
- package/dist/handles.d.ts +57 -0
- package/dist/handles.d.ts.map +1 -0
- package/dist/handles.js +1375 -0
- package/dist/handles.js.map +1 -0
- package/dist/hosted-runtime.d.ts +33 -0
- package/dist/hosted-runtime.d.ts.map +1 -0
- package/dist/hosted-runtime.js +99 -0
- package/dist/hosted-runtime.js.map +1 -0
- package/dist/hosted-ui.d.ts +84 -0
- package/dist/hosted-ui.d.ts.map +1 -0
- package/dist/hosted-ui.js +673 -0
- package/dist/hosted-ui.js.map +1 -0
- package/dist/importer.d.ts +22 -0
- package/dist/importer.d.ts.map +1 -0
- package/dist/importer.js +54 -0
- package/dist/importer.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +132 -0
- package/dist/index.js.map +1 -0
- package/dist/init-keys.d.ts +3 -0
- package/dist/init-keys.d.ts.map +1 -0
- package/dist/init-keys.js +13 -0
- package/dist/init-keys.js.map +1 -0
- package/dist/internal.d.ts +6 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +17 -0
- package/dist/internal.js.map +1 -0
- package/dist/jwt.d.ts +3 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +22 -0
- package/dist/jwt.js.map +1 -0
- package/dist/launch-context.d.ts +4 -0
- package/dist/launch-context.d.ts.map +1 -0
- package/dist/launch-context.js +44 -0
- package/dist/launch-context.js.map +1 -0
- package/dist/login-hint.d.ts +4 -0
- package/dist/login-hint.d.ts.map +1 -0
- package/dist/login-hint.js +63 -0
- package/dist/login-hint.js.map +1 -0
- package/dist/mutate-batching.d.ts +14 -0
- package/dist/mutate-batching.d.ts.map +1 -0
- package/dist/mutate-batching.js +65 -0
- package/dist/mutate-batching.js.map +1 -0
- package/dist/open-document.d.ts +127 -0
- package/dist/open-document.d.ts.map +1 -0
- package/dist/open-document.js +2121 -0
- package/dist/open-document.js.map +1 -0
- package/dist/page-title.d.ts +3 -0
- package/dist/page-title.d.ts.map +1 -0
- package/dist/page-title.js +32 -0
- package/dist/page-title.js.map +1 -0
- package/dist/perf.d.ts +9 -0
- package/dist/perf.d.ts.map +1 -0
- package/dist/perf.js +39 -0
- package/dist/perf.js.map +1 -0
- package/dist/presence.d.ts +62 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +331 -0
- package/dist/presence.js.map +1 -0
- package/dist/record-paging.d.ts +99 -0
- package/dist/record-paging.d.ts.map +1 -0
- package/dist/record-paging.js +220 -0
- package/dist/record-paging.js.map +1 -0
- package/dist/schema-conflict-dialog.d.ts +10 -0
- package/dist/schema-conflict-dialog.d.ts.map +1 -0
- package/dist/schema-conflict-dialog.js +164 -0
- package/dist/schema-conflict-dialog.js.map +1 -0
- package/dist/selection-persistence.d.ts +5 -0
- package/dist/selection-persistence.d.ts.map +1 -0
- package/dist/selection-persistence.js +90 -0
- package/dist/selection-persistence.js.map +1 -0
- package/dist/serializer.d.ts +3 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/serializer.js +2 -0
- package/dist/serializer.js.map +1 -0
- package/dist/session-persistence.d.ts +4 -0
- package/dist/session-persistence.d.ts.map +1 -0
- package/dist/session-persistence.js +68 -0
- package/dist/session-persistence.js.map +1 -0
- package/dist/session-toolbar.d.ts +62 -0
- package/dist/session-toolbar.d.ts.map +1 -0
- package/dist/session-toolbar.js +1205 -0
- package/dist/session-toolbar.js.map +1 -0
- package/dist/session.d.ts +69 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +926 -0
- package/dist/session.js.map +1 -0
- package/dist/tail-ops.d.ts +28 -0
- package/dist/tail-ops.d.ts.map +1 -0
- package/dist/tail-ops.js +46 -0
- package/dist/tail-ops.js.map +1 -0
- package/dist/topic-lifecycle.d.ts +41 -0
- package/dist/topic-lifecycle.d.ts.map +1 -0
- package/dist/topic-lifecycle.js +169 -0
- package/dist/topic-lifecycle.js.map +1 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/undo.d.ts +18 -0
- package/dist/undo.d.ts.map +1 -0
- package/dist/undo.js +110 -0
- package/dist/undo.js.map +1 -0
- package/dist/version-bar.d.ts +22 -0
- package/dist/version-bar.d.ts.map +1 -0
- package/dist/version-bar.js +169 -0
- package/dist/version-bar.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +8 -0
- package/dist/version.js.map +1 -0
- package/dist/vite.d.ts +15 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +36 -0
- package/dist/vite.js.map +1 -0
- package/dist/ws-client.d.ts +53 -0
- package/dist/ws-client.d.ts.map +1 -0
- package/dist/ws-client.js +604 -0
- package/dist/ws-client.js.map +1 -0
- package/dist/ws-frame-limit.d.ts +21 -0
- package/dist/ws-frame-limit.d.ts.map +1 -0
- package/dist/ws-frame-limit.js +40 -0
- package/dist/ws-frame-limit.js.map +1 -0
- package/docs/app-manifest.md +65 -0
- package/docs/custom-chrome.md +147 -0
- package/docs/hosted-ui-advanced.md +77 -0
- package/docs/imported-documents.md +261 -0
- package/docs/presence.md +129 -0
- package/docs/schemas.md +135 -0
- package/docs/streams.md +248 -0
- package/package.json +60 -0
- package/scripts/prepare.mjs +50 -0
- package/src/api-fetch.ts +127 -0
- package/src/api-headers.ts +28 -0
- package/src/auth-flow.ts +125 -0
- package/src/client.ts +1457 -0
- package/src/doc-url-sync.ts +183 -0
- package/src/document-branches.ts +124 -0
- package/src/document-checkpoints.ts +135 -0
- package/src/document-commands.ts +651 -0
- package/src/document-signals.ts +234 -0
- package/src/document-streams.ts +132 -0
- package/src/document-thumbnail-capture.ts +191 -0
- package/src/documents-namespace.ts +516 -0
- package/src/documents.ts +2426 -0
- package/src/emitter.ts +129 -0
- package/src/errors.ts +45 -0
- package/src/export-guest.ts +282 -0
- package/src/fetch-retry.ts +119 -0
- package/src/guest-link.ts +14 -0
- package/src/handles.ts +1731 -0
- package/src/hosted-runtime.ts +109 -0
- package/src/hosted-ui.ts +1020 -0
- package/src/importer.ts +89 -0
- package/src/index.ts +267 -0
- package/src/init-keys.ts +15 -0
- package/src/internal.ts +23 -0
- package/src/jwt.ts +18 -0
- package/src/launch-context.ts +43 -0
- package/src/login-hint.ts +60 -0
- package/src/mutate-batching.ts +63 -0
- package/src/open-document.ts +2869 -0
- package/src/page-title.ts +33 -0
- package/src/perf.ts +46 -0
- package/src/presence.ts +471 -0
- package/src/record-paging.ts +270 -0
- package/src/schema-conflict-dialog.ts +176 -0
- package/src/selection-persistence.ts +98 -0
- package/src/serializer.ts +15 -0
- package/src/session-persistence.ts +69 -0
- package/src/session-toolbar.ts +1457 -0
- package/src/session.ts +1262 -0
- package/src/tail-ops.ts +63 -0
- package/src/topic-lifecycle.ts +217 -0
- package/src/types.ts +75 -0
- package/src/undo.ts +125 -0
- package/src/version-bar.ts +221 -0
- package/src/version.ts +8 -0
- package/src/vite.ts +49 -0
- package/src/ws-client.ts +678 -0
- package/src/ws-frame-limit.ts +52 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Document lifecycle signals: server-pushed listener-fanout surfaces a
|
|
2
|
+
// Document exposes, separate from the CRDT state it wraps. Pure subscriber
|
|
3
|
+
// registries with a load-bearing emit discipline:
|
|
4
|
+
//
|
|
5
|
+
// - `GoneSignal` fire-once-then-cache (a doc is evicted once)
|
|
6
|
+
// - `WorkStatusSignal` latest-retained, re-emit per phase
|
|
7
|
+
// - `DriveStatusSignal` latest-retained, fire-on-attach, dedup-on-emit
|
|
8
|
+
import { createEmitter } from './emitter.js';
|
|
9
|
+
// Each signal is a `createEmitter` composed with the retain / attach / dedup
|
|
10
|
+
// policy its wire event needs, wrapped in a small class only to keep the
|
|
11
|
+
// domain-named methods (`mark`, `emit`, `status`, `clearListeners`) the
|
|
12
|
+
// Document calls. The shared emit discipline (swallow-and-log, fire-on-attach
|
|
13
|
+
// in a microtask, retain the last value) lives in the primitive; the class
|
|
14
|
+
// picks the options.
|
|
15
|
+
// Fire-once-then-cache signal for `doc_gone`: listeners registered AFTER the
|
|
16
|
+
// event still fire exactly once on attach (the `Promise`-resolution pattern),
|
|
17
|
+
// so callback-wiring after the WS frame may have landed has no race. `mark` is
|
|
18
|
+
// idempotent (both `doc:<id>` and `presence:doc:<id>` fan out a frame, so the
|
|
19
|
+
// one-shot collapses them to a single listener fire).
|
|
20
|
+
export class GoneSignal {
|
|
21
|
+
_emitter = createEmitter({
|
|
22
|
+
fireOnAttach: true,
|
|
23
|
+
retain: 'oneShot',
|
|
24
|
+
onError: (err) => {
|
|
25
|
+
// A consumer throw must not strand the others or break the WS router.
|
|
26
|
+
console.error('[Brass] onGone listener threw:', err);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
get reason() {
|
|
30
|
+
return this._emitter.retained ?? null;
|
|
31
|
+
}
|
|
32
|
+
on(cb) {
|
|
33
|
+
return this._emitter.on(cb);
|
|
34
|
+
}
|
|
35
|
+
mark(reason) {
|
|
36
|
+
this._emitter.emit(reason);
|
|
37
|
+
}
|
|
38
|
+
// Drop app-side listeners (suspend / close). The cached reason is NOT
|
|
39
|
+
// cleared: a `_markGone` that already fired stays terminal across a suspend.
|
|
40
|
+
clearListeners() {
|
|
41
|
+
this._emitter.clear();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Latest-retained, re-emit-per-phase signal for `doc_status`. Not one-shot:
|
|
45
|
+
// phases arrive repeatedly until terminal (`pending: false`), and the latest
|
|
46
|
+
// is retained so a late subscriber still sees the final state.
|
|
47
|
+
export class WorkStatusSignal {
|
|
48
|
+
_emitter = createEmitter({
|
|
49
|
+
fireOnAttach: true,
|
|
50
|
+
retain: 'latest',
|
|
51
|
+
onError: (err) => {
|
|
52
|
+
console.error('[Brass] onStatus listener threw:', err);
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
get status() {
|
|
56
|
+
return this._emitter.retained ?? null;
|
|
57
|
+
}
|
|
58
|
+
on(cb) {
|
|
59
|
+
return this._emitter.on(cb);
|
|
60
|
+
}
|
|
61
|
+
emit(status) {
|
|
62
|
+
this._emitter.emit(status);
|
|
63
|
+
}
|
|
64
|
+
clearListeners() {
|
|
65
|
+
this._emitter.clear();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Latest-retained, fire-on-attach signal for `doc_drive_status`. Like
|
|
69
|
+
// `WorkStatusSignal`, but `emit` short-circuits when the new status
|
|
70
|
+
// deep-equals the retained one: drive status fans out on *every* METADATA row
|
|
71
|
+
// change (rename, thumbnail, edit), so the equality gate keeps `onDriveStatus`
|
|
72
|
+
// from re-firing when the tracking state didn't move.
|
|
73
|
+
export class DriveStatusSignal {
|
|
74
|
+
_emitter = createEmitter({
|
|
75
|
+
fireOnAttach: true,
|
|
76
|
+
retain: 'latest',
|
|
77
|
+
equals: driveStatusEqual,
|
|
78
|
+
onError: (err) => {
|
|
79
|
+
console.error('[Brass] onDriveStatus listener threw:', err);
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
get status() {
|
|
83
|
+
return this._emitter.retained ?? null;
|
|
84
|
+
}
|
|
85
|
+
on(cb) {
|
|
86
|
+
return this._emitter.on(cb);
|
|
87
|
+
}
|
|
88
|
+
emit(status) {
|
|
89
|
+
this._emitter.emit(status);
|
|
90
|
+
}
|
|
91
|
+
clearListeners() {
|
|
92
|
+
this._emitter.clear();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Field-by-field equality for the drive status. The shape is flat (all
|
|
96
|
+
// scalars), so a key compare suffices; explicit rather than JSON.stringify so
|
|
97
|
+
// a future non-scalar field forces a conscious update here.
|
|
98
|
+
function driveStatusEqual(a, b) {
|
|
99
|
+
return (a.driveType === b.driveType &&
|
|
100
|
+
a.driveName === b.driveName &&
|
|
101
|
+
a.state === b.state &&
|
|
102
|
+
a.canPush === b.canPush &&
|
|
103
|
+
a.label === b.label &&
|
|
104
|
+
a.detail === b.detail &&
|
|
105
|
+
a.broken === b.broken &&
|
|
106
|
+
a.pushReplacesRemote === b.pushReplacesRemote &&
|
|
107
|
+
a.mirrorDirection === b.mirrorDirection &&
|
|
108
|
+
a.ref === b.ref &&
|
|
109
|
+
a.refUpdatedAt === b.refUpdatedAt &&
|
|
110
|
+
a.publishing === b.publishing &&
|
|
111
|
+
a.itemName === b.itemName &&
|
|
112
|
+
a.itemUrl === b.itemUrl);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=document-signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-signals.js","sourceRoot":"","sources":["../src/document-signals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Document, DocumentMutator, DocumentSubscriber, DocumentUnsubscribe, EntityProxy } from './documents.js';
|
|
2
|
+
import type { DocumentStreamInfo } from './documents-namespace.js';
|
|
3
|
+
import type { ListHandle, MapHandle, OrderedMapHandle } from './handles.js';
|
|
4
|
+
export interface StreamRuntime {
|
|
5
|
+
list(): Promise<DocumentStreamInfo[]>;
|
|
6
|
+
create(name: string): Promise<DocumentStreamInfo>;
|
|
7
|
+
openLine(lineId: string): Promise<Document>;
|
|
8
|
+
}
|
|
9
|
+
export declare class DocumentStream {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
private readonly _ownsInner;
|
|
12
|
+
map<T = unknown>(key: string): MapHandle<T>;
|
|
13
|
+
list<T = unknown>(key: string): ListHandle<T>;
|
|
14
|
+
orderedMap<T = unknown>(mapKey: string, orderKey: string): OrderedMapHandle<T>;
|
|
15
|
+
mutate<E extends object = EntityProxy>(fn: (d: DocumentMutator<E>) => void): void;
|
|
16
|
+
toJSON(): Record<string, unknown>;
|
|
17
|
+
subscribe(cb: DocumentSubscriber): DocumentUnsubscribe;
|
|
18
|
+
undo(): boolean;
|
|
19
|
+
redo(): boolean;
|
|
20
|
+
sealUndoStep(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=document-streams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-streams.d.ts","sourceRoot":"","sources":["../src/document-streams.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAO5E,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACtC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC7C;AAED,qBAAa,cAAc;IAGzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAQtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IAWrC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAI3C,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAI7C,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAI9E,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,EACnC,EAAE,EAAE,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,GAClC,IAAI;IAIP,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIjC,SAAS,CAAC,EAAE,EAAE,kBAAkB,GAAG,mBAAmB;IAOtD,IAAI,IAAI,OAAO;IAIf,IAAI,IAAI,OAAO;IAUf,YAAY,IAAI,IAAI;CAiCrB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Per-stream scope of a Document. A document is a container of streams:
|
|
2
|
+
// named, independently-loadable CRDT units. `doc.stream(name)` resolves
|
|
3
|
+
// one and returns this wrapper; only the streams an app touches are
|
|
4
|
+
// downloaded, imported, and subscribed, so open cost scales with use,
|
|
5
|
+
// not with the whole document.
|
|
6
|
+
//
|
|
7
|
+
// Each non-default stream is backed by its own internal Document wired
|
|
8
|
+
// to the stream's line (its own snapshot + op channel); the wrapper
|
|
9
|
+
// exposes the per-stream subset of the Document surface. The `default`
|
|
10
|
+
// stream wraps the parent Document itself, so `doc.stream('default')`
|
|
11
|
+
// and the doc-level handles read the same state.
|
|
12
|
+
export class DocumentStream {
|
|
13
|
+
// The stream's name within the document ('default' for the document's
|
|
14
|
+
// own default state).
|
|
15
|
+
name;
|
|
16
|
+
/** @internal The Document holding this stream's state. For a
|
|
17
|
+
* non-default stream that is its own line's Document; for `default` it
|
|
18
|
+
* is the parent itself, which is why `_ownsInner` gates the close. */
|
|
19
|
+
_inner;
|
|
20
|
+
// True when this wrapper owns its inner Document (a non-default
|
|
21
|
+
// stream): closing the parent closes it. The default stream's inner IS
|
|
22
|
+
// the parent, which owns its own lifecycle.
|
|
23
|
+
_ownsInner;
|
|
24
|
+
/** @internal */
|
|
25
|
+
constructor(name, inner, ownsInner) {
|
|
26
|
+
this.name = name;
|
|
27
|
+
this._inner = inner;
|
|
28
|
+
this._ownsInner = ownsInner;
|
|
29
|
+
}
|
|
30
|
+
// Typed container handles, scoped to this stream. Same surface and
|
|
31
|
+
// semantics as the doc-level `doc.map` / `doc.list` / `doc.orderedMap`.
|
|
32
|
+
map(key) {
|
|
33
|
+
return this._inner.map(key);
|
|
34
|
+
}
|
|
35
|
+
list(key) {
|
|
36
|
+
return this._inner.list(key);
|
|
37
|
+
}
|
|
38
|
+
orderedMap(mapKey, orderKey) {
|
|
39
|
+
return this._inner.orderedMap(mapKey, orderKey);
|
|
40
|
+
}
|
|
41
|
+
mutate(fn) {
|
|
42
|
+
this._inner.mutate(fn);
|
|
43
|
+
}
|
|
44
|
+
toJSON() {
|
|
45
|
+
return this._inner.toJSON();
|
|
46
|
+
}
|
|
47
|
+
subscribe(cb) {
|
|
48
|
+
return this._inner.subscribe(cb);
|
|
49
|
+
}
|
|
50
|
+
// Per-stream undo/redo: each stream keeps its own local-edit stack
|
|
51
|
+
// (its edits are its own CRDT commits). The doc-level `doc.undo()`
|
|
52
|
+
// covers only the default stream.
|
|
53
|
+
undo() {
|
|
54
|
+
return this._inner.undo();
|
|
55
|
+
}
|
|
56
|
+
redo() {
|
|
57
|
+
return this._inner.redo();
|
|
58
|
+
}
|
|
59
|
+
// Seal the stream's open undo group, so the next local edit starts a
|
|
60
|
+
// fresh undo step. Local and synchronous (no server call). Call it
|
|
61
|
+
// when a user operation completes: commits group into one step until
|
|
62
|
+
// sealed (the same same-stroke collapsing the doc-level undo has), so
|
|
63
|
+
// an app that never seals gets one giant step per session. The
|
|
64
|
+
// cross-stream operation recipe in `docs/streams.md` is built on this.
|
|
65
|
+
sealUndoStep() {
|
|
66
|
+
this._inner._sealUndoStep();
|
|
67
|
+
}
|
|
68
|
+
/** @internal The stream's live head seq (advanced by its own op channel),
|
|
69
|
+
* or `null` before the transport resolves it. Internal for the same
|
|
70
|
+
* reason the document's is, and a stream has even less use for one: it
|
|
71
|
+
* carries no checkpoint machinery to anchor. */
|
|
72
|
+
get currentSeq() {
|
|
73
|
+
return this._inner.currentSeq;
|
|
74
|
+
}
|
|
75
|
+
/** @internal Preview this stream at a historical line seq, or return it
|
|
76
|
+
* to its live head when `seq` is undefined. Driven by the parent
|
|
77
|
+
* Document's version preview so a partitioned document previews
|
|
78
|
+
* consistently across streams. A no-op when the inner has no checkout
|
|
79
|
+
* fetcher (a guest line, which holds no token to fetch at-version), so
|
|
80
|
+
* such a stream stays live. */
|
|
81
|
+
async _previewAt(seq) {
|
|
82
|
+
const inner = this._inner;
|
|
83
|
+
if (seq !== undefined && inner._hasCheckoutFetcher()) {
|
|
84
|
+
await inner._checkoutVersion(seq);
|
|
85
|
+
}
|
|
86
|
+
else if (inner._isCheckedOut()) {
|
|
87
|
+
inner.returnToHead();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** @internal Close the stream's own transport + state. Called by the
|
|
91
|
+
* parent Document's close; a no-op for the default stream, whose inner
|
|
92
|
+
* is the parent itself. */
|
|
93
|
+
_close() {
|
|
94
|
+
if (this._ownsInner)
|
|
95
|
+
this._inner.close();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=document-streams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-streams.js","sourceRoot":"","sources":["../src/document-streams.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,wEAAwE;AACxE,oEAAoE;AACpE,sEAAsE;AACtE,+BAA+B;AAC/B,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AACpE,uEAAuE;AACvE,sEAAsE;AACtE,iDAAiD;AAuBjD,MAAM,OAAO,cAAc;IACzB,sEAAsE;IACtE,sBAAsB;IACb,IAAI,CAAS;IACtB;;2EAEuE;IAC9D,MAAM,CAAW;IAC1B,gEAAgE;IAChE,uEAAuE;IACvE,4CAA4C;IAC3B,UAAU,CAAU;IAErC,gBAAgB;IAChB,YAAY,IAAY,EAAE,KAAe,EAAE,SAAkB;QAC3D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,mEAAmE;IACnE,wEAAwE;IACxE,GAAG,CAAc,GAAW;QAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,CAAc,GAAW;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAI,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,UAAU,CAAc,MAAc,EAAE,QAAgB;QACtD,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAI,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CACJ,EAAmC;QAEnC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,SAAS,CAAC,EAAsB;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,mEAAmE;IACnE,mEAAmE;IACnE,kCAAkC;IAClC,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,qEAAqE;IACrE,mEAAmE;IACnE,qEAAqE;IACrE,sEAAsE;IACtE,+DAA+D;IAC/D,uEAAuE;IACvE,YAAY;QACV,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;IAC9B,CAAC;IAED;;;qDAGiD;IACjD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;IAChC,CAAC;IAED;;;;;mCAK+B;IAC/B,KAAK,CAAC,UAAU,CAAC,GAAuB;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,mBAAmB,EAAE,EAAE,CAAC;YACrD,MAAM,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;YACjC,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;+BAE2B;IAC3B,MAAM;QACJ,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type CanvasSource = HTMLCanvasElement | (() => HTMLCanvasElement | null);
|
|
2
|
+
export type ThumbnailUploader = (image: Blob, width: number, height: number) => Promise<void>;
|
|
3
|
+
export declare function fitWithinMaxEdge(width: number, height: number, maxEdge: number): {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
scaled: boolean;
|
|
7
|
+
};
|
|
8
|
+
export interface ThumbnailCaptureHost {
|
|
9
|
+
isCaptureAllowed(): boolean;
|
|
10
|
+
isAttached(): boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class ThumbnailCapture {
|
|
13
|
+
private readonly host;
|
|
14
|
+
private _canvas;
|
|
15
|
+
private _timer;
|
|
16
|
+
private _warnedFor;
|
|
17
|
+
private _uploader;
|
|
18
|
+
constructor(host: ThumbnailCaptureHost);
|
|
19
|
+
useCanvas(source: CanvasSource): () => void;
|
|
20
|
+
setUploader(uploader: ThumbnailUploader | null): void;
|
|
21
|
+
schedule(): void;
|
|
22
|
+
cancel(): void;
|
|
23
|
+
private _capture;
|
|
24
|
+
private _downscale;
|
|
25
|
+
private _warnIfWebglContextWillProduceBlankCapture;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=document-thumbnail-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-thumbnail-capture.d.ts","sourceRoot":"","sources":["../src/document-thumbnail-capture.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GACpB,iBAAiB,GACjB,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,CAAC;AAErC,MAAM,MAAM,iBAAiB,GAAG,CAC9B,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,IAAI,CAAC,CAAC;AAoBnB,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAWpD;AAED,MAAM,WAAW,oBAAoB;IAInC,gBAAgB,IAAI,OAAO,CAAC;IAG5B,UAAU,IAAI,OAAO,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAYf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAVjC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAA8C;IAG5D,OAAO,CAAC,UAAU,CAAkC;IAIpD,OAAO,CAAC,SAAS,CAAkC;gBAEtB,IAAI,EAAE,oBAAoB;IAKvD,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,IAAI;IAY3C,WAAW,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAMrD,QAAQ,IAAI,IAAI;IAUhB,MAAM,IAAI,IAAI;YAOA,QAAQ;IAkCtB,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,0CAA0C;CAyBnD"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Document thumbnail auto-capture: screenshots a registered canvas after each
|
|
2
|
+
// local edit settles and uploads it as the thumbnail. One debounce timer, an
|
|
3
|
+
// injected uploader, and a one-shot WebGL diagnostic.
|
|
4
|
+
// Debounce window: a screenshot is taken this long after the last local edit,
|
|
5
|
+
// so a continuous drag uploads once when it settles, not once per frame.
|
|
6
|
+
const THUMBNAIL_CAPTURE_DEBOUNCE_MS = 1500;
|
|
7
|
+
// Longest-edge cap (device pixels) for an uploaded thumbnail: a generous
|
|
8
|
+
// product ceiling, an upper bound on the size any Brass surface sensibly
|
|
9
|
+
// paints a thumbnail at with retina headroom. The largest surface (the
|
|
10
|
+
// version-history timeline, ~200px) clears 2x DPR with room, while this still
|
|
11
|
+
// sheds the multi-megapixel frames a full-resolution 3D / map / CAD canvas
|
|
12
|
+
// would upload. Standalone (not derived from a CSS size) because the display
|
|
13
|
+
// sizes live in the frontend and this is a published SDK; a smaller
|
|
14
|
+
// per-surface derivative is a server-side concern.
|
|
15
|
+
const MAX_THUMBNAIL_CAPTURE_EDGE = 512;
|
|
16
|
+
// Cap the longest edge to `maxEdge`, preserving aspect ratio, never upscaling:
|
|
17
|
+
// a canvas within the cap is uploaded at native size (`scaled: false`), so the
|
|
18
|
+
// common small-canvas case skips the offscreen redraw. The returned dimensions
|
|
19
|
+
// are what the uploader reports, so they stay matched to the bytes.
|
|
20
|
+
export function fitWithinMaxEdge(width, height, maxEdge) {
|
|
21
|
+
const longest = Math.max(width, height);
|
|
22
|
+
if (!Number.isFinite(longest) || longest <= 0 || longest <= maxEdge) {
|
|
23
|
+
return { width, height, scaled: false };
|
|
24
|
+
}
|
|
25
|
+
const ratio = maxEdge / longest;
|
|
26
|
+
return {
|
|
27
|
+
width: Math.max(1, Math.round(width * ratio)),
|
|
28
|
+
height: Math.max(1, Math.round(height * ratio)),
|
|
29
|
+
scaled: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export class ThumbnailCapture {
|
|
33
|
+
host;
|
|
34
|
+
// Canvas registered via `useCanvas`; `null` for the common non-canvas app.
|
|
35
|
+
_canvas = null;
|
|
36
|
+
_timer = null;
|
|
37
|
+
// The canvas already warned about `preserveDrawingBuffer: false`, so the
|
|
38
|
+
// warn fires once per canvas; reset on `useCanvas` for a re-register.
|
|
39
|
+
_warnedFor = null;
|
|
40
|
+
// Injected upload hook (the Document owns no HTTP client). `null` on the
|
|
41
|
+
// offline / test path, where the canvas is tracked but never captured, so
|
|
42
|
+
// apps can register one early without hitting the server in tests.
|
|
43
|
+
_uploader = null;
|
|
44
|
+
constructor(host) {
|
|
45
|
+
this.host = host;
|
|
46
|
+
}
|
|
47
|
+
// Register a canvas (element or lazy getter) to screenshot as the thumbnail.
|
|
48
|
+
// Returns an unregister handle; re-registering replaces. The caller
|
|
49
|
+
// (Document) arms its Loro subscriber so local commits reach `schedule()`.
|
|
50
|
+
useCanvas(source) {
|
|
51
|
+
this._canvas = source;
|
|
52
|
+
// A re-register gets one more chance to surface the missing-buffer warn.
|
|
53
|
+
this._warnedFor = null;
|
|
54
|
+
return () => {
|
|
55
|
+
if (this._canvas === source) {
|
|
56
|
+
this._canvas = null;
|
|
57
|
+
this.cancel();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
setUploader(uploader) {
|
|
62
|
+
this._uploader = uploader;
|
|
63
|
+
}
|
|
64
|
+
// Called from the Document's local-commit dispatch; debounces so a burst of
|
|
65
|
+
// edits produces ONE upload when it settles.
|
|
66
|
+
schedule() {
|
|
67
|
+
if (this._canvas === null)
|
|
68
|
+
return;
|
|
69
|
+
if (this._timer !== null)
|
|
70
|
+
clearTimeout(this._timer);
|
|
71
|
+
this._timer = setTimeout(() => {
|
|
72
|
+
this._timer = null;
|
|
73
|
+
void this._capture();
|
|
74
|
+
}, THUMBNAIL_CAPTURE_DEBOUNCE_MS);
|
|
75
|
+
}
|
|
76
|
+
// Cancel a pending capture (canvas unregistered / suspend / close).
|
|
77
|
+
cancel() {
|
|
78
|
+
if (this._timer !== null) {
|
|
79
|
+
clearTimeout(this._timer);
|
|
80
|
+
this._timer = null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async _capture() {
|
|
84
|
+
if (!this.host.isCaptureAllowed())
|
|
85
|
+
return;
|
|
86
|
+
if (this._canvas === null)
|
|
87
|
+
return;
|
|
88
|
+
if (this._uploader === null)
|
|
89
|
+
return;
|
|
90
|
+
const el = typeof this._canvas === 'function' ? this._canvas() : this._canvas;
|
|
91
|
+
if (!el)
|
|
92
|
+
return;
|
|
93
|
+
this._warnIfWebglContextWillProduceBlankCapture(el);
|
|
94
|
+
try {
|
|
95
|
+
const target = fitWithinMaxEdge(el.width, el.height, MAX_THUMBNAIL_CAPTURE_EDGE);
|
|
96
|
+
const source = target.scaled ? this._downscale(el, target) : el;
|
|
97
|
+
const image = await new Promise((resolve, reject) => {
|
|
98
|
+
source.toBlob((blob) => {
|
|
99
|
+
if (blob)
|
|
100
|
+
resolve(blob);
|
|
101
|
+
else
|
|
102
|
+
reject(new Error('thumbnail capture: canvas produced no image'));
|
|
103
|
+
}, 'image/png');
|
|
104
|
+
});
|
|
105
|
+
if (!this.host.isAttached())
|
|
106
|
+
return;
|
|
107
|
+
await this._uploader(image, target.width, target.height);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Best-effort: rate-limit rejection, lack of write access, or a
|
|
111
|
+
// transient failure is swallowed; the next local edit reschedules.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Redraw an oversized canvas into an offscreen 2D canvas at the capped
|
|
115
|
+
// dimensions. `drawImage` reads the source's front buffer, so the WebGL
|
|
116
|
+
// `preserveDrawingBuffer` caveat above applies here too. If a 2D context
|
|
117
|
+
// can't be acquired, fall back to the full-resolution source: one oversized
|
|
118
|
+
// upload beats a missing thumbnail.
|
|
119
|
+
_downscale(el, target) {
|
|
120
|
+
const off = document.createElement('canvas');
|
|
121
|
+
off.width = target.width;
|
|
122
|
+
off.height = target.height;
|
|
123
|
+
const ctx = off.getContext('2d');
|
|
124
|
+
if (!ctx)
|
|
125
|
+
return el;
|
|
126
|
+
ctx.drawImage(el, 0, 0, target.width, target.height);
|
|
127
|
+
return off;
|
|
128
|
+
}
|
|
129
|
+
// Warn once per canvas if its WebGL context lacks
|
|
130
|
+
// `preserveDrawingBuffer: true`: without it `toBlob` reads back a blank
|
|
131
|
+
// frame (the spec lets the browser discard the drawing buffer after
|
|
132
|
+
// compositing), so the upload silently stores a blank PNG with no
|
|
133
|
+
// diagnostic. Harmless on 2D / SVG canvases (no WebGL context to inspect).
|
|
134
|
+
_warnIfWebglContextWillProduceBlankCapture(el) {
|
|
135
|
+
if (this._warnedFor === el)
|
|
136
|
+
return;
|
|
137
|
+
if (typeof el.getContext !== 'function')
|
|
138
|
+
return;
|
|
139
|
+
let gl = null;
|
|
140
|
+
try {
|
|
141
|
+
gl =
|
|
142
|
+
el.getContext('webgl2') ??
|
|
143
|
+
el.getContext('webgl');
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (!gl)
|
|
149
|
+
return;
|
|
150
|
+
const attributes = gl.getContextAttributes();
|
|
151
|
+
if (attributes && attributes.preserveDrawingBuffer === false) {
|
|
152
|
+
this._warnedFor = el;
|
|
153
|
+
console.warn('@brass-build/client: useCanvas captured a blank thumbnail because ' +
|
|
154
|
+
'the WebGL context was created with preserveDrawingBuffer: false. ' +
|
|
155
|
+
'Pass preserveDrawingBuffer: true when creating the WebGL context ' +
|
|
156
|
+
'(e.g., new THREE.WebGLRenderer({ preserveDrawingBuffer: true })).');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=document-thumbnail-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-thumbnail-capture.js","sourceRoot":"","sources":["../src/document-thumbnail-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { Document } from './documents.js';
|
|
2
|
+
import type { ImportClaimResponse } from './importer.js';
|
|
3
|
+
export type DocumentRole = 'owner' | 'editor' | 'viewer';
|
|
4
|
+
export interface DocumentMember {
|
|
5
|
+
sub: string;
|
|
6
|
+
role: DocumentRole;
|
|
7
|
+
granted_at: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DocumentThumbnail {
|
|
10
|
+
url: string;
|
|
11
|
+
version: number;
|
|
12
|
+
branch_id: string;
|
|
13
|
+
content_type: string;
|
|
14
|
+
width: number | null;
|
|
15
|
+
height: number | null;
|
|
16
|
+
created_at: string;
|
|
17
|
+
expires_at: string;
|
|
18
|
+
}
|
|
19
|
+
export interface DocumentSummary {
|
|
20
|
+
doc_id: string;
|
|
21
|
+
organization_id: string;
|
|
22
|
+
project_id: string | null;
|
|
23
|
+
name: string;
|
|
24
|
+
created_at: string;
|
|
25
|
+
updated_at: string;
|
|
26
|
+
owner_sub: string;
|
|
27
|
+
deleted_at?: string;
|
|
28
|
+
thumbnail?: DocumentThumbnail;
|
|
29
|
+
}
|
|
30
|
+
export interface DocumentSourceStream {
|
|
31
|
+
name: string;
|
|
32
|
+
url: string;
|
|
33
|
+
content_type: string;
|
|
34
|
+
byte_size: number;
|
|
35
|
+
}
|
|
36
|
+
export interface DocumentSourceBlob {
|
|
37
|
+
url: string;
|
|
38
|
+
filename: string;
|
|
39
|
+
content_type: string;
|
|
40
|
+
byte_size: number;
|
|
41
|
+
expires_in: number;
|
|
42
|
+
streams: DocumentSourceStream[];
|
|
43
|
+
}
|
|
44
|
+
export interface DocumentRecord extends DocumentSummary {
|
|
45
|
+
role: DocumentRole;
|
|
46
|
+
members: DocumentMember[];
|
|
47
|
+
app_metadata?: Record<string, unknown>;
|
|
48
|
+
location_label: string | null;
|
|
49
|
+
downloadable: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface DocumentStreamInfo {
|
|
52
|
+
name: string;
|
|
53
|
+
format: string;
|
|
54
|
+
line_id: string;
|
|
55
|
+
created_at: string;
|
|
56
|
+
created_by: string;
|
|
57
|
+
}
|
|
58
|
+
export interface BranchSummary {
|
|
59
|
+
branch_id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
created_at: string;
|
|
62
|
+
created_by: string;
|
|
63
|
+
is_default: boolean;
|
|
64
|
+
created_from: {
|
|
65
|
+
branch_id: string;
|
|
66
|
+
version: number;
|
|
67
|
+
} | null;
|
|
68
|
+
current_seq: number;
|
|
69
|
+
}
|
|
70
|
+
export interface SetThumbnailInput {
|
|
71
|
+
image: Blob | ArrayBuffer | Uint8Array;
|
|
72
|
+
contentType?: string;
|
|
73
|
+
width?: number;
|
|
74
|
+
height?: number;
|
|
75
|
+
}
|
|
76
|
+
export interface GetThumbnailOptions {
|
|
77
|
+
version?: number;
|
|
78
|
+
branch?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface DocumentCheckpoint {
|
|
81
|
+
version: number;
|
|
82
|
+
branch_id: string;
|
|
83
|
+
created_by: string;
|
|
84
|
+
created_at: string;
|
|
85
|
+
}
|
|
86
|
+
export interface PushToDriveInput {
|
|
87
|
+
message?: string;
|
|
88
|
+
}
|
|
89
|
+
export interface PushToDriveResult {
|
|
90
|
+
new_ref: string;
|
|
91
|
+
pending?: boolean;
|
|
92
|
+
entity_count: number;
|
|
93
|
+
pushed_at: string;
|
|
94
|
+
}
|
|
95
|
+
export interface CreateBranchRequest {
|
|
96
|
+
from_version?: number;
|
|
97
|
+
from_branch_id?: string;
|
|
98
|
+
name?: string;
|
|
99
|
+
}
|
|
100
|
+
export interface DocumentsNamespace {
|
|
101
|
+
get(docId: string): Promise<DocumentRecord>;
|
|
102
|
+
setThumbnail(doc: Document, input: SetThumbnailInput): Promise<DocumentThumbnail>;
|
|
103
|
+
getThumbnail(docId: string, options?: GetThumbnailOptions): Promise<DocumentThumbnail | null>;
|
|
104
|
+
}
|
|
105
|
+
export interface DocumentsInternalNamespace {
|
|
106
|
+
createCheckpoint(doc: Document): Promise<DocumentCheckpoint>;
|
|
107
|
+
listBranches(docId: string): Promise<{
|
|
108
|
+
default_branch_id: string;
|
|
109
|
+
branches: BranchSummary[];
|
|
110
|
+
}>;
|
|
111
|
+
listStreams(docId: string, branchId: string): Promise<{
|
|
112
|
+
branch_id: string;
|
|
113
|
+
streams: DocumentStreamInfo[];
|
|
114
|
+
}>;
|
|
115
|
+
createStream(docId: string, branchId: string, name: string): Promise<DocumentStreamInfo>;
|
|
116
|
+
createBranch(docId: string, input: CreateBranchRequest): Promise<BranchSummary>;
|
|
117
|
+
pushToDrive(doc: Document, input?: PushToDriveInput): Promise<PushToDriveResult>;
|
|
118
|
+
sourceBlob(doc: Document): Promise<DocumentSourceBlob>;
|
|
119
|
+
claimImport(docId: string): Promise<ImportClaimResponse>;
|
|
120
|
+
completeImport(docId: string): Promise<{
|
|
121
|
+
schema_ref: {
|
|
122
|
+
app_id: string;
|
|
123
|
+
schema_hash: string;
|
|
124
|
+
};
|
|
125
|
+
}>;
|
|
126
|
+
}
|
|
127
|
+
interface DocumentsFactoryOptions {
|
|
128
|
+
apiBaseUrl: string;
|
|
129
|
+
getAccessToken: () => Promise<string | null>;
|
|
130
|
+
getAppAssertion?: () => Promise<string | null>;
|
|
131
|
+
}
|
|
132
|
+
export declare function createDocumentsNamespace(opts: DocumentsFactoryOptions): DocumentsNamespace & DocumentsInternalNamespace;
|
|
133
|
+
export {};
|
|
134
|
+
//# sourceMappingURL=documents-namespace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents-namespace.d.ts","sourceRoot":"","sources":["../src/documents-namespace.ts"],"names":[],"mappings":"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"}
|