@starlove/orbit 1.4.1 → 2.0.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/Dockerfile +10 -8
- package/README.md +146 -164
- package/dist/full/csp.txt +1 -0
- package/dist/full/fonts/JetBrains_Mono/JetBrainsMono-subset.woff2 +0 -0
- package/dist/full/fonts/JetBrains_Mono/README.txt +5 -0
- package/dist/full/fonts/Mona_Sans/MonaSans-subset.woff2 +0 -0
- package/{public/fonts/Open_Sans → dist/full/fonts/Mona_Sans}/OFL.txt +93 -93
- package/dist/full/fonts/Mona_Sans/README.txt +10 -0
- package/{public/fonts/JetBrains_Mono → dist/full/fonts/Newsreader}/OFL.txt +93 -93
- package/dist/full/fonts/Newsreader/README.txt +8 -0
- package/dist/full/fonts/Newsreader/newsreader.woff2 +0 -0
- package/dist/full/index.html +36 -653
- package/dist/full/js/app.BmuponPJ.js +32 -0
- package/dist/full/js/app.BmuponPJ.js.map +1 -0
- package/dist/full/js/chunk.1fJGQGbW.js +2 -0
- package/dist/full/js/chunk.1fJGQGbW.js.map +1 -0
- package/dist/full/js/chunk.5D7JO2zp.js +2 -0
- package/dist/full/js/chunk.5D7JO2zp.js.map +1 -0
- package/dist/full/js/chunk.BrNn_D79.js +2 -0
- package/dist/full/js/chunk.BrNn_D79.js.map +1 -0
- package/dist/full/js/chunk.CokJXIqM.js +2 -0
- package/dist/full/js/chunk.CokJXIqM.js.map +1 -0
- package/dist/full/js/chunk.D_Haqy6R.js +2 -0
- package/dist/full/js/chunk.D_Haqy6R.js.map +1 -0
- package/dist/full/js/chunk.RO0jsH6I.js +15 -0
- package/dist/full/js/chunk.RO0jsH6I.js.map +1 -0
- package/dist/full/js/chunk.dqWOEtBM.js +2 -0
- package/dist/full/js/chunk.dqWOEtBM.js.map +1 -0
- package/dist/full/js/warm.f260bbbc.js +15 -0
- package/dist/full/orbits-favicon.png +0 -0
- package/dist/full/orbits-logo-bg-wide.png +0 -0
- package/dist/full/orbits-logo-bg.png +0 -0
- package/dist/full/orbits-logo.png +0 -0
- package/dist/full/styles.2b154ffe.css +1 -0
- package/dist/full/vendor/starlove-ui/theme-init.js +66 -0
- package/dist/full/version.json +2 -2
- package/docs/AGENT_GUIDE.md +114 -0
- package/docs/UPDATING.md +249 -64
- package/lib/adapters/indexeddb/blobs.d.ts +3 -0
- package/lib/adapters/indexeddb/blobs.js +54 -0
- package/lib/adapters/indexeddb/database.d.ts +60 -0
- package/lib/adapters/indexeddb/database.js +126 -0
- package/lib/adapters/indexeddb/index.d.ts +5 -0
- package/lib/adapters/indexeddb/index.js +3 -0
- package/lib/adapters/indexeddb/locks.d.ts +14 -0
- package/lib/adapters/indexeddb/locks.js +40 -0
- package/lib/adapters/indexeddb/store.d.ts +40 -0
- package/lib/adapters/indexeddb/store.js +424 -0
- package/lib/adapters/indexeddb/tables.d.ts +43 -0
- package/lib/adapters/indexeddb/tables.js +127 -0
- package/lib/adapters/memory/blobs.d.ts +3 -0
- package/lib/adapters/memory/blobs.js +44 -0
- package/lib/adapters/memory/board.d.ts +41 -0
- package/lib/adapters/memory/board.js +521 -0
- package/lib/adapters/memory/index.d.ts +2 -0
- package/lib/adapters/memory/index.js +2 -0
- package/lib/adapters/memory/search.d.ts +6 -0
- package/lib/adapters/memory/search.js +30 -0
- package/lib/adapters/memory/store.d.ts +34 -0
- package/lib/adapters/memory/store.js +266 -0
- package/lib/adapters/sqlite/backups.d.ts +53 -0
- package/lib/adapters/sqlite/backups.js +232 -0
- package/lib/adapters/sqlite/blobs.d.ts +14 -0
- package/lib/adapters/sqlite/blobs.js +109 -0
- package/lib/adapters/sqlite/board.d.ts +77 -0
- package/lib/adapters/sqlite/board.js +328 -0
- package/lib/adapters/sqlite/database.d.ts +67 -0
- package/lib/adapters/sqlite/database.js +285 -0
- package/lib/adapters/sqlite/index.d.ts +3 -0
- package/lib/adapters/sqlite/index.js +2 -0
- package/lib/adapters/sqlite/lock.d.ts +11 -0
- package/lib/adapters/sqlite/lock.js +34 -0
- package/lib/adapters/sqlite/records.d.ts +54 -0
- package/lib/adapters/sqlite/records.js +546 -0
- package/lib/adapters/sqlite/schema.d.ts +54 -0
- package/lib/adapters/sqlite/schema.js +276 -0
- package/lib/adapters/sqlite/store.d.ts +39 -0
- package/lib/adapters/sqlite/store.js +385 -0
- package/lib/browser/in-page.d.ts +31 -0
- package/lib/browser/in-page.js +46 -0
- package/lib/browser/old-preview.d.ts +13 -0
- package/lib/browser/old-preview.js +80 -0
- package/lib/browser/preview-board.d.ts +8 -0
- package/lib/browser/preview-board.js +69 -0
- package/lib/cli/main.d.ts +7 -0
- package/lib/cli/main.js +343 -0
- package/lib/cli/orbit.d.ts +8 -0
- package/lib/cli/orbit.js +25 -0
- package/lib/client/http.d.ts +38 -0
- package/lib/client/http.js +334 -0
- package/lib/client/local.d.ts +26 -0
- package/lib/client/local.js +190 -0
- package/lib/client/object-url.d.ts +8 -0
- package/lib/client/object-url.js +21 -0
- package/lib/client/types.d.ts +268 -0
- package/lib/client/types.js +8 -0
- package/lib/commands/agent-tools.d.ts +31 -0
- package/lib/commands/agent-tools.js +100 -0
- package/lib/commands/index.d.ts +56 -0
- package/lib/commands/index.js +298 -0
- package/lib/commands/parse.d.ts +73 -0
- package/lib/commands/parse.js +231 -0
- package/lib/commands/present.d.ts +134 -0
- package/lib/commands/present.js +198 -0
- package/lib/commands/session.d.ts +85 -0
- package/lib/commands/session.js +138 -0
- package/lib/commands/verbs.d.ts +35 -0
- package/lib/commands/verbs.js +842 -0
- package/lib/core/actors.d.ts +18 -0
- package/lib/core/actors.js +45 -0
- package/lib/core/agent.d.ts +128 -0
- package/lib/core/agent.js +323 -0
- package/lib/core/boards.d.ts +113 -0
- package/lib/core/boards.js +288 -0
- package/lib/core/bootstrap.d.ts +47 -0
- package/lib/core/bootstrap.js +100 -0
- package/lib/core/bytes.d.ts +10 -0
- package/lib/core/bytes.js +52 -0
- package/lib/core/card-paths.d.ts +25 -0
- package/lib/core/card-paths.js +44 -0
- package/lib/core/context.d.ts +60 -0
- package/lib/core/context.js +42 -0
- package/lib/core/cross-board.d.ts +81 -0
- package/lib/core/cross-board.js +228 -0
- package/lib/core/describe.d.ts +21 -0
- package/lib/core/describe.js +81 -0
- package/lib/core/errors.d.ts +159 -0
- package/lib/core/errors.js +160 -0
- package/lib/core/files.d.ts +79 -0
- package/lib/core/files.js +262 -0
- package/lib/core/history.d.ts +20 -0
- package/lib/core/history.js +53 -0
- package/lib/core/image-types.d.ts +16 -0
- package/lib/core/image-types.js +36 -0
- package/lib/core/model.d.ts +263 -0
- package/lib/core/model.js +34 -0
- package/lib/core/nebula-link.d.ts +14 -0
- package/lib/core/nebula-link.js +39 -0
- package/lib/core/relations.d.ts +58 -0
- package/lib/core/relations.js +112 -0
- package/lib/core/search.d.ts +38 -0
- package/lib/core/search.js +92 -0
- package/lib/core/sessions.d.ts +44 -0
- package/lib/core/sessions.js +158 -0
- package/lib/core/snapshot-schema.d.ts +295 -0
- package/lib/core/snapshot-schema.js +82 -0
- package/lib/core/snapshots.d.ts +75 -0
- package/lib/core/snapshots.js +409 -0
- package/lib/core/states.d.ts +25 -0
- package/lib/core/states.js +126 -0
- package/lib/core/text.d.ts +40 -0
- package/lib/core/text.js +113 -0
- package/lib/core/tickets.d.ts +69 -0
- package/lib/core/tickets.js +311 -0
- package/lib/core/trello.d.ts +17 -0
- package/lib/core/trello.js +269 -0
- package/lib/core/verdicts.d.ts +28 -0
- package/lib/core/verdicts.js +92 -0
- package/lib/core/views.d.ts +95 -0
- package/lib/core/views.js +186 -0
- package/lib/http/app.d.ts +46 -0
- package/lib/http/app.js +491 -0
- package/lib/mcp-server.d.ts +10 -0
- package/lib/mcp-server.js +120 -0
- package/lib/node/assets.d.ts +7 -0
- package/lib/node/assets.js +68 -0
- package/lib/node/data-folder.d.ts +21 -0
- package/lib/node/data-folder.js +34 -0
- package/lib/node/env.d.ts +38 -0
- package/lib/node/env.js +49 -0
- package/lib/node/host-check.d.ts +24 -0
- package/lib/node/host-check.js +53 -0
- package/lib/node/host-services.d.ts +9 -0
- package/lib/node/host-services.js +150 -0
- package/lib/node/local.d.ts +22 -0
- package/lib/node/local.js +61 -0
- package/lib/node/migrate.d.ts +53 -0
- package/lib/node/migrate.js +635 -0
- package/lib/node/package.d.ts +7 -0
- package/lib/node/package.js +14 -0
- package/lib/node/repo-board.d.ts +49 -0
- package/lib/node/repo-board.js +245 -0
- package/lib/node/serve.d.ts +8 -0
- package/lib/node/serve.js +106 -0
- package/lib/orbit.d.ts +47 -0
- package/lib/orbit.js +44 -0
- package/lib/quiet-sqlite-warning.d.ts +1 -0
- package/lib/quiet-sqlite-warning.js +18 -0
- package/lib/store/blob-path.d.ts +6 -0
- package/lib/store/blob-path.js +12 -0
- package/lib/store/conformance.d.ts +52 -0
- package/lib/store/conformance.js +1449 -0
- package/lib/store/search-words.d.ts +10 -0
- package/lib/store/search-words.js +19 -0
- package/lib/store/types.d.ts +452 -0
- package/lib/store/types.js +34 -0
- package/llms.txt +63 -0
- package/package.json +109 -25
- package/src/cli/orbit.js +11 -658
- package/src/mcp-server.js +16 -876
- package/SKILL-ORBIT.md +0 -151
- package/build.mjs +0 -210
- package/dist/full/js/app.4e6fbe20.js +0 -952
- package/dist/full/js/app.4e6fbe20.js.map +0 -7
- package/dist/full/styles.4e60d824.css +0 -1
- package/docs/AGENT_PROTOCOL.md +0 -424
- package/docs/MCP_SETUP.md +0 -54
- package/docs/ORBIT_DISPATCH.md +0 -280
- package/docs/SS-Orbit-Dark.png +0 -0
- package/docs/SS-Orbit-Light.png +0 -0
- package/docs/mcp-client.example.json +0 -13
- package/docs/setup/orbit-init-wizard.md +0 -174
- package/public/apple-touch-icon.png +0 -0
- package/public/cursors/live_arrow.cur +0 -0
- package/public/cursors/live_link.cur +0 -0
- package/public/cursors/live_move.cur +0 -0
- package/public/cursors/live_select.cur +0 -0
- package/public/cursors/live_unavail.cur +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Bold.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-BoldItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Italic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Light.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-LightItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Medium.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-MediumItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Regular.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-SemiBold.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-SemiBoldItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/OFL.txt +0 -93
- package/public/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf +0 -0
- package/public/fonts/Inter/Inter-VariableFont_opsz,wght.ttf +0 -0
- package/public/fonts/Inter/OFL.txt +0 -93
- package/public/fonts/Inter/README.txt +0 -118
- package/public/fonts/JetBrains_Mono/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- package/public/fonts/JetBrains_Mono/JetBrainsMono-VariableFont_wght.ttf +0 -0
- package/public/fonts/JetBrains_Mono/README.txt +0 -79
- package/public/fonts/OpenRing-Regular.ttf +0 -0
- package/public/fonts/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/public/fonts/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- package/public/fonts/Open_Sans/README.txt +0 -100
- package/public/fonts/Orbitron/OFL.txt +0 -93
- package/public/fonts/Orbitron/Orbitron-VariableFont_wght.ttf +0 -0
- package/public/fonts/Orbitron/README.txt +0 -68
- package/public/fonts/Rajdhani/OFL.txt +0 -93
- package/public/fonts/Rajdhani/Rajdhani-Bold.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Light.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Medium.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Regular.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-SemiBold.ttf +0 -0
- package/public/fonts/runescape-uf.ttf +0 -0
- package/public/index.html +0 -769
- package/public/js/actor-labels.js +0 -65
- package/public/js/api.js +0 -39
- package/public/js/app.js +0 -45
- package/public/js/artifact-drawer.js +0 -79
- package/public/js/board-export.js +0 -161
- package/public/js/board-menu.js +0 -374
- package/public/js/card-actions.js +0 -545
- package/public/js/config.js +0 -20
- package/public/js/create-card.js +0 -190
- package/public/js/dom.js +0 -19
- package/public/js/drawer.js +0 -273
- package/public/js/font-preference.js +0 -230
- package/public/js/format.js +0 -433
- package/public/js/help-menu.js +0 -31
- package/public/js/icons.js +0 -16
- package/public/js/kanban.js +0 -694
- package/public/js/local-backend.js +0 -1015
- package/public/js/main.js +0 -161
- package/public/js/modal.js +0 -33
- package/public/js/motion-preference.js +0 -64
- package/public/js/panel.js +0 -58
- package/public/js/router.js +0 -134
- package/public/js/search.js +0 -56
- package/public/js/settings-tabs.js +0 -7
- package/public/js/settings.js +0 -1634
- package/public/js/sse.js +0 -159
- package/public/js/starscape.js +0 -332
- package/public/js/state.js +0 -129
- package/public/js/text-editing.js +0 -128
- package/public/js/theme-preference.js +0 -95
- package/public/js/ticket-detail.js +0 -1516
- package/public/js/ticket-typeahead.js +0 -49
- package/public/js/toast.js +0 -89
- package/public/js/topbar-notes.js +0 -155
- package/public/js/transport.js +0 -22
- package/public/js/typeahead.js +0 -206
- package/public/js/unread.js +0 -121
- package/public/js/update-check.js +0 -58
- package/public/js/url-routes.js +0 -94
- package/public/orbits-favicon.png +0 -0
- package/public/orbits-logo-bg-wide.png +0 -0
- package/public/orbits-logo-bg.png +0 -0
- package/public/orbits-logo.png +0 -0
- package/public/styles.css +0 -7709
- package/src/core/agent.js +0 -387
- package/src/core/agents-md.js +0 -109
- package/src/core/artifacts.js +0 -149
- package/src/core/attachments.js +0 -238
- package/src/core/auth.js +0 -85
- package/src/core/backups.js +0 -142
- package/src/core/board.js +0 -148
- package/src/core/boards.js +0 -409
- package/src/core/bootstrap.js +0 -170
- package/src/core/css-bundle.js +0 -30
- package/src/core/db.js +0 -315
- package/src/core/delete-board.js +0 -163
- package/src/core/dispatch.js +0 -1007
- package/src/core/events.js +0 -314
- package/src/core/http.js +0 -115
- package/src/core/migrate.js +0 -198
- package/src/core/paths.js +0 -55
- package/src/core/provision-repo-board.js +0 -119
- package/src/core/queries.js +0 -246
- package/src/core/registry.js +0 -211
- package/src/core/relations.js +0 -163
- package/src/core/review-verdicts.js +0 -138
- package/src/core/router.js +0 -556
- package/src/core/search.js +0 -183
- package/src/core/seed.js +0 -234
- package/src/core/snapshots.js +0 -692
- package/src/core/states.js +0 -167
- package/src/core/system-picker.js +0 -109
- package/src/core/tickets.js +0 -400
- package/src/core/util.js +0 -106
- package/src/core/version-check.js +0 -154
- package/src/mcp/orbit-client.js +0 -287
- package/src/server.js +0 -115
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The IndexedDB database the adapter keeps one Orbit in, and the one way it
|
|
3
|
+
* talks to it: `transact()`, a transaction whose requests are all made from
|
|
4
|
+
* IndexedDB's own callbacks. An IndexedDB transaction commits by itself as
|
|
5
|
+
* soon as its code waits for anything else, so nothing here awaits inside a
|
|
6
|
+
* transaction; a write's body runs before, against memory (./store.ts).
|
|
7
|
+
*
|
|
8
|
+
* Object stores (schema version 1):
|
|
9
|
+
*
|
|
10
|
+
* boards the list of boards, by id, as { n, board }: `n` counts up as
|
|
11
|
+
* boards are made, for the port's "then by when it was made"
|
|
12
|
+
* settings small values, by key
|
|
13
|
+
* heads per board: `revision`, raised by every commit, and `seq`, the
|
|
14
|
+
* last sequence number given to a row
|
|
15
|
+
* rows every record of every board, keyed [board id, table, key], as
|
|
16
|
+
* { t: table, s: sequence, v: record }; the sequence keeps the
|
|
17
|
+
* order records were written in, which the port's lists follow
|
|
18
|
+
* blobs bytes, keyed [board id, path]
|
|
19
|
+
*/
|
|
20
|
+
import { OrbitError } from "../../core/errors.ts";
|
|
21
|
+
import type { RegisteredBoard } from "../../core/model.ts";
|
|
22
|
+
export declare const SCHEMA_VERSION = 1;
|
|
23
|
+
export declare const BOARDS = "boards";
|
|
24
|
+
export declare const SETTINGS = "settings";
|
|
25
|
+
export declare const HEADS = "heads";
|
|
26
|
+
export declare const ROWS = "rows";
|
|
27
|
+
export declare const BLOBS = "blobs";
|
|
28
|
+
/** Per board: what the last commit left. */
|
|
29
|
+
export interface Head {
|
|
30
|
+
board_id: string;
|
|
31
|
+
revision: number;
|
|
32
|
+
seq: number;
|
|
33
|
+
}
|
|
34
|
+
/** A board's listing as stored: `n` is its place in the order boards were made. */
|
|
35
|
+
export interface Listed {
|
|
36
|
+
n: number;
|
|
37
|
+
board: RegisteredBoard;
|
|
38
|
+
}
|
|
39
|
+
/** One record as stored: its table, its sequence number, the record. */
|
|
40
|
+
export interface Row {
|
|
41
|
+
t: string;
|
|
42
|
+
s: number;
|
|
43
|
+
v: unknown;
|
|
44
|
+
}
|
|
45
|
+
export type RowKey = [string, string, string];
|
|
46
|
+
/** Every row of a board, or of one of its tables. */
|
|
47
|
+
export declare function rowRange(boardId: string, table?: string): IDBKeyRange;
|
|
48
|
+
/** Every blob of a board. */
|
|
49
|
+
export declare function blobRange(boardId: string): IDBKeyRange;
|
|
50
|
+
/** A browser's own failure as the port's: a full disk is `storage_full`, the rest `storage_failed`. */
|
|
51
|
+
export declare function storageError(error: unknown): OrbitError;
|
|
52
|
+
/** Opens (and on first use makes) the database. A database of a newer schema is refused with `data_from_newer_orbit`. */
|
|
53
|
+
export declare function openDatabase(factory: IDBFactory, name: string): Promise<IDBDatabase>;
|
|
54
|
+
/**
|
|
55
|
+
* Runs `script` as one transaction. The script makes its requests at once
|
|
56
|
+
* and from their callbacks, and returns a function that reads its answer
|
|
57
|
+
* once the transaction has committed. `refuse(error)` aborts it: nothing it
|
|
58
|
+
* wrote remains, and the promise rejects with that error.
|
|
59
|
+
*/
|
|
60
|
+
export declare function transact<T>(db: IDBDatabase, stores: readonly string[], mode: IDBTransactionMode, script: (tx: IDBTransaction, refuse: (error: OrbitError) => void) => () => T): Promise<T>;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The IndexedDB database the adapter keeps one Orbit in, and the one way it
|
|
4
|
+
* talks to it: `transact()`, a transaction whose requests are all made from
|
|
5
|
+
* IndexedDB's own callbacks. An IndexedDB transaction commits by itself as
|
|
6
|
+
* soon as its code waits for anything else, so nothing here awaits inside a
|
|
7
|
+
* transaction; a write's body runs before, against memory (./store.ts).
|
|
8
|
+
*
|
|
9
|
+
* Object stores (schema version 1):
|
|
10
|
+
*
|
|
11
|
+
* boards the list of boards, by id, as { n, board }: `n` counts up as
|
|
12
|
+
* boards are made, for the port's "then by when it was made"
|
|
13
|
+
* settings small values, by key
|
|
14
|
+
* heads per board: `revision`, raised by every commit, and `seq`, the
|
|
15
|
+
* last sequence number given to a row
|
|
16
|
+
* rows every record of every board, keyed [board id, table, key], as
|
|
17
|
+
* { t: table, s: sequence, v: record }; the sequence keeps the
|
|
18
|
+
* order records were written in, which the port's lists follow
|
|
19
|
+
* blobs bytes, keyed [board id, path]
|
|
20
|
+
*/
|
|
21
|
+
import { OrbitError, isOrbitError } from "../../core/errors.js";
|
|
22
|
+
export const SCHEMA_VERSION = 1;
|
|
23
|
+
export const BOARDS = "boards";
|
|
24
|
+
export const SETTINGS = "settings";
|
|
25
|
+
export const HEADS = "heads";
|
|
26
|
+
export const ROWS = "rows";
|
|
27
|
+
export const BLOBS = "blobs";
|
|
28
|
+
/** Every row of a board, or of one of its tables. */
|
|
29
|
+
export function rowRange(boardId, table) {
|
|
30
|
+
return table === undefined ? IDBKeyRange.bound([boardId], [boardId, []]) : IDBKeyRange.bound([boardId, table], [boardId, table, []]);
|
|
31
|
+
}
|
|
32
|
+
/** Every blob of a board. */
|
|
33
|
+
export function blobRange(boardId) {
|
|
34
|
+
return IDBKeyRange.bound([boardId], [boardId, []]);
|
|
35
|
+
}
|
|
36
|
+
/** A browser's own failure as the port's: a full disk is `storage_full`, the rest `storage_failed`. */
|
|
37
|
+
export function storageError(error) {
|
|
38
|
+
if (isOrbitError(error))
|
|
39
|
+
return error;
|
|
40
|
+
const name = error instanceof Error || (typeof DOMException !== "undefined" && error instanceof DOMException) ? error.name : "";
|
|
41
|
+
return new OrbitError(name === "QuotaExceededError" ? "storage_full" : "storage_failed", { cause: error });
|
|
42
|
+
}
|
|
43
|
+
/** Opens (and on first use makes) the database. A database of a newer schema is refused with `data_from_newer_orbit`. */
|
|
44
|
+
export function openDatabase(factory, name) {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
let request;
|
|
47
|
+
try {
|
|
48
|
+
request = factory.open(name, SCHEMA_VERSION);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
reject(storageError(error));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
request.onupgradeneeded = () => {
|
|
55
|
+
const db = request.result;
|
|
56
|
+
const make = (store, options) => {
|
|
57
|
+
if (!db.objectStoreNames.contains(store))
|
|
58
|
+
db.createObjectStore(store, options);
|
|
59
|
+
};
|
|
60
|
+
make(BOARDS);
|
|
61
|
+
make(SETTINGS);
|
|
62
|
+
make(HEADS, { keyPath: "board_id" });
|
|
63
|
+
make(ROWS);
|
|
64
|
+
make(BLOBS);
|
|
65
|
+
};
|
|
66
|
+
request.onsuccess = () => {
|
|
67
|
+
const db = request.result;
|
|
68
|
+
// Another tab is opening a newer schema: let it.
|
|
69
|
+
db.onversionchange = () => {
|
|
70
|
+
db.close();
|
|
71
|
+
};
|
|
72
|
+
resolve(db);
|
|
73
|
+
};
|
|
74
|
+
request.onerror = () => {
|
|
75
|
+
reject(request.error?.name === "VersionError" ? new OrbitError("data_from_newer_orbit", { cause: request.error }) : storageError(request.error));
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Runs `script` as one transaction. The script makes its requests at once
|
|
81
|
+
* and from their callbacks, and returns a function that reads its answer
|
|
82
|
+
* once the transaction has committed. `refuse(error)` aborts it: nothing it
|
|
83
|
+
* wrote remains, and the promise rejects with that error.
|
|
84
|
+
*/
|
|
85
|
+
export function transact(db, stores, mode, script) {
|
|
86
|
+
return new Promise((resolve, reject) => {
|
|
87
|
+
let tx;
|
|
88
|
+
try {
|
|
89
|
+
tx = db.transaction(stores, mode);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
reject(storageError(error));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
let refusal = null;
|
|
96
|
+
const refuse = (error) => {
|
|
97
|
+
if (refusal)
|
|
98
|
+
return;
|
|
99
|
+
refusal = error;
|
|
100
|
+
try {
|
|
101
|
+
tx.abort();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Already finished or aborting.
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
let answer = () => undefined;
|
|
108
|
+
tx.oncomplete = () => {
|
|
109
|
+
try {
|
|
110
|
+
resolve(answer());
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
reject(storageError(error));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
tx.onabort = () => {
|
|
117
|
+
reject(refusal ?? storageError(tx.error));
|
|
118
|
+
};
|
|
119
|
+
try {
|
|
120
|
+
answer = script(tx, refuse);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
refuse(storageError(error));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { openIndexedDbStore } from "./store.ts";
|
|
2
|
+
export type { IndexedDbStore, IndexedDbStoreOptions } from "./store.ts";
|
|
3
|
+
export { createIndexedDbBlobStore } from "./blobs.ts";
|
|
4
|
+
export { createLocalLocks, webLocks } from "./locks.ts";
|
|
5
|
+
export type { Locks } from "./locks.ts";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The exclusive locks the IndexedDB adapter serialises a board's writes with.
|
|
3
|
+
* In a browser they are Web Locks (`navigator.locks`), which hold across every
|
|
4
|
+
* tab of the origin. `createLocalLocks()` is the same promise inside one
|
|
5
|
+
* JavaScript realm, for tests and for a page that has no Web Locks.
|
|
6
|
+
*/
|
|
7
|
+
export interface Locks {
|
|
8
|
+
/** Runs `body` once no other holder of `name` is running, and resolves with what it returns. */
|
|
9
|
+
request<T>(name: string, body: () => Promise<T>): Promise<T>;
|
|
10
|
+
}
|
|
11
|
+
/** The browser's Web Locks, or null where there are none. */
|
|
12
|
+
export declare function webLocks(): Locks | null;
|
|
13
|
+
/** Locks held in this realm only: first come, first served, per name. */
|
|
14
|
+
export declare function createLocalLocks(): Locks;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The exclusive locks the IndexedDB adapter serialises a board's writes with.
|
|
4
|
+
* In a browser they are Web Locks (`navigator.locks`), which hold across every
|
|
5
|
+
* tab of the origin. `createLocalLocks()` is the same promise inside one
|
|
6
|
+
* JavaScript realm, for tests and for a page that has no Web Locks.
|
|
7
|
+
*/
|
|
8
|
+
/** The browser's Web Locks, or null where there are none. */
|
|
9
|
+
export function webLocks() {
|
|
10
|
+
const manager = globalThis.navigator?.locks;
|
|
11
|
+
if (!manager)
|
|
12
|
+
return null;
|
|
13
|
+
return {
|
|
14
|
+
request: (name, body) => manager.request(name, () => body())
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Locks held in this realm only: first come, first served, per name. */
|
|
18
|
+
export function createLocalLocks() {
|
|
19
|
+
const tails = new Map();
|
|
20
|
+
return {
|
|
21
|
+
async request(name, body) {
|
|
22
|
+
const previous = tails.get(name) ?? Promise.resolve();
|
|
23
|
+
let release = () => undefined;
|
|
24
|
+
const done = new Promise((resolve) => {
|
|
25
|
+
release = resolve;
|
|
26
|
+
});
|
|
27
|
+
const tail = previous.then(() => done);
|
|
28
|
+
tails.set(name, tail);
|
|
29
|
+
await previous;
|
|
30
|
+
try {
|
|
31
|
+
return await body();
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
release();
|
|
35
|
+
if (tails.get(name) === tail)
|
|
36
|
+
tails.delete(name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The IndexedDB adapter: Orbit's storage port in a browser, shared by every
|
|
3
|
+
* tab of the origin. `openIndexedDbStore()` gives the store and, as its
|
|
4
|
+
* `blobs`, the blob store of the same database.
|
|
5
|
+
*
|
|
6
|
+
* - **Writes.** An IndexedDB transaction commits by itself once its code
|
|
7
|
+
* waits for anything else, so a write can't be one. A write takes the
|
|
8
|
+
* board's exclusive lock (a Web Lock, held across tabs), runs its body
|
|
9
|
+
* against a copy of the board in memory (the memory adapter's writer, so
|
|
10
|
+
* its reads see its own changes and the port's checks are the same), then
|
|
11
|
+
* commits what changed in one readwrite transaction. A body that throws
|
|
12
|
+
* commits nothing. Card numbers are given under the lock.
|
|
13
|
+
* - **Reads.** A read loads the board in one readonly transaction, which is
|
|
14
|
+
* one committed state, and runs its body against it. It takes no lock, so
|
|
15
|
+
* a read never waits for a write. A tab keeps the board it last loaded and
|
|
16
|
+
* reuses it while the board's revision is unchanged.
|
|
17
|
+
* - **watch().** This tab's commits reach its watchers at once; other tabs'
|
|
18
|
+
* through a BroadcastChannel, after which the board is read again and the
|
|
19
|
+
* events past the last one heard are delivered, in order, once.
|
|
20
|
+
* - **Search** filters a board's documents in memory, as the memory adapter
|
|
21
|
+
* does: a board's documents are few.
|
|
22
|
+
* - **Backups:** none (`backups` is null); people export a board instead.
|
|
23
|
+
*/
|
|
24
|
+
import type { BlobStore, OrbitStore } from "../../store/types.ts";
|
|
25
|
+
import type { Locks } from "./locks.ts";
|
|
26
|
+
export interface IndexedDbStoreOptions {
|
|
27
|
+
/** The database's name. Default: `orbit`. */
|
|
28
|
+
name?: string;
|
|
29
|
+
/** Default: the page's `indexedDB`. */
|
|
30
|
+
indexedDB?: IDBFactory;
|
|
31
|
+
/** The locks that serialise a board's writes. Default: the page's Web Locks (`navigator.locks`), else locks within this page. */
|
|
32
|
+
locks?: Locks;
|
|
33
|
+
/** How tabs tell each other about commits. Default: BroadcastChannel; null for none (this tab only). */
|
|
34
|
+
channel?: ((name: string) => BroadcastChannel) | null;
|
|
35
|
+
}
|
|
36
|
+
export interface IndexedDbStore extends OrbitStore {
|
|
37
|
+
/** The bytes of the same database. */
|
|
38
|
+
readonly blobs: BlobStore;
|
|
39
|
+
}
|
|
40
|
+
export declare function openIndexedDbStore(options?: IndexedDbStoreOptions): Promise<IndexedDbStore>;
|