@graview/ship 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/LICENSE +96 -0
- package/README.md +95 -0
- package/dist/browser-adapter.d.ts +84 -0
- package/dist/browser-adapter.d.ts.map +1 -0
- package/dist/browser-adapter.js +111 -0
- package/dist/browser-adapter.js.map +1 -0
- package/dist/browser.d.ts +26 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +16 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +48 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +170 -0
- package/dist/cli.js.map +1 -0
- package/dist/dev.d.ts +148 -0
- package/dist/dev.d.ts.map +1 -0
- package/dist/dev.js +286 -0
- package/dist/dev.js.map +1 -0
- package/dist/door.d.ts +22 -0
- package/dist/door.d.ts.map +1 -0
- package/dist/door.js +43 -0
- package/dist/door.js.map +1 -0
- package/dist/export.d.ts +25 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +30 -0
- package/dist/export.js.map +1 -0
- package/dist/file-adapter.d.ts +28 -0
- package/dist/file-adapter.d.ts.map +1 -0
- package/dist/file-adapter.js +50 -0
- package/dist/file-adapter.js.map +1 -0
- package/dist/health.d.ts +19 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +16 -0
- package/dist/health.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations.d.ts +31 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +59 -0
- package/dist/migrations.js.map +1 -0
- package/dist/open-store.d.ts +57 -0
- package/dist/open-store.d.ts.map +1 -0
- package/dist/open-store.js +103 -0
- package/dist/open-store.js.map +1 -0
- package/dist/photos.d.ts +89 -0
- package/dist/photos.d.ts.map +1 -0
- package/dist/photos.js +102 -0
- package/dist/photos.js.map +1 -0
- package/dist/presence.d.ts +33 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +99 -0
- package/dist/presence.js.map +1 -0
- package/dist/remote.d.ts +73 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +271 -0
- package/dist/remote.js.map +1 -0
- package/dist/serve.d.ts +121 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +249 -0
- package/dist/serve.js.map +1 -0
- package/dist/snapshot.d.ts +20 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +41 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/source-edit.d.ts +52 -0
- package/dist/source-edit.d.ts.map +1 -0
- package/dist/source-edit.js +455 -0
- package/dist/source-edit.js.map +1 -0
- package/dist/steps.d.ts +98 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/steps.js +189 -0
- package/dist/steps.js.map +1 -0
- package/dist/studio-door.d.ts +36 -0
- package/dist/studio-door.d.ts.map +1 -0
- package/dist/studio-door.js +102 -0
- package/dist/studio-door.js.map +1 -0
- package/dist/sync-seed.d.ts +61 -0
- package/dist/sync-seed.d.ts.map +1 -0
- package/dist/sync-seed.js +95 -0
- package/dist/sync-seed.js.map +1 -0
- package/dist/typecheck.d.ts +15 -0
- package/dist/typecheck.d.ts.map +1 -0
- package/dist/typecheck.js +59 -0
- package/dist/typecheck.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Elastic License 2.0
|
|
2
|
+
|
|
3
|
+
## Acceptance
|
|
4
|
+
|
|
5
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
6
|
+
|
|
7
|
+
## Copyright License
|
|
8
|
+
|
|
9
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide,
|
|
10
|
+
non-sublicensable, non-transferable license to use, copy, distribute, make
|
|
11
|
+
available, and prepare derivative works of the software, in each case subject
|
|
12
|
+
to the limitations and conditions below.
|
|
13
|
+
|
|
14
|
+
## Limitations
|
|
15
|
+
|
|
16
|
+
You may not provide the software to third parties as a hosted or managed
|
|
17
|
+
service, where the service provides users with access to any substantial set
|
|
18
|
+
of the features or functionality of the software.
|
|
19
|
+
|
|
20
|
+
You may not move, change, disable, or circumvent the license key
|
|
21
|
+
functionality in the software, and you may not remove or obscure any
|
|
22
|
+
functionality in the software that is protected by the license key.
|
|
23
|
+
|
|
24
|
+
You may not alter, remove, or obscure any licensing, copyright, or other
|
|
25
|
+
notices of the licensor in the software. Any use of the licensor's trademarks
|
|
26
|
+
is subject to applicable law.
|
|
27
|
+
|
|
28
|
+
## Patents
|
|
29
|
+
|
|
30
|
+
The licensor grants you a license, under any patent claims the licensor can
|
|
31
|
+
license, or becomes able to license, to make, have made, use, sell, offer for
|
|
32
|
+
sale, import and have imported the software, in each case subject to the
|
|
33
|
+
limitations and conditions in this license. This license does not cover any
|
|
34
|
+
patent claims that you cause to be infringed by modifications or additions to
|
|
35
|
+
the software. If you or your company make any written claim that the software
|
|
36
|
+
infringes or contributes to infringement of any patent, your patent license
|
|
37
|
+
for the software granted under these terms ends immediately. If your company
|
|
38
|
+
makes such a claim, your patent license ends immediately for work on behalf
|
|
39
|
+
of your company.
|
|
40
|
+
|
|
41
|
+
## Notices
|
|
42
|
+
|
|
43
|
+
You must ensure that anyone who gets a copy of any part of the software from
|
|
44
|
+
you also gets a copy of these terms.
|
|
45
|
+
|
|
46
|
+
If you modify the software, you must include in any modified copies of the
|
|
47
|
+
software prominent notices stating that you have modified the software.
|
|
48
|
+
|
|
49
|
+
## No Other Rights
|
|
50
|
+
|
|
51
|
+
These terms do not imply any licenses other than those expressly granted in
|
|
52
|
+
these terms.
|
|
53
|
+
|
|
54
|
+
## Termination
|
|
55
|
+
|
|
56
|
+
If you use the software in violation of these terms, such use is not
|
|
57
|
+
licensed, and your licenses will automatically terminate. If the licensor
|
|
58
|
+
provides you with a notice of your violation, and you cease all violation of
|
|
59
|
+
this license no later than 30 days after you receive that notice, your
|
|
60
|
+
licenses will be reinstated retroactively. However, if you violate these
|
|
61
|
+
terms after such reinstatement, any additional violation of these terms will
|
|
62
|
+
cause your licenses to terminate automatically and permanently.
|
|
63
|
+
|
|
64
|
+
## No Liability
|
|
65
|
+
|
|
66
|
+
*As far as the law allows, the software comes as is, without any warranty or
|
|
67
|
+
condition, and the licensor will not be liable to you for any damages arising
|
|
68
|
+
out of these terms or the use or nature of the software, under any kind of
|
|
69
|
+
legal claim.*
|
|
70
|
+
|
|
71
|
+
## Definitions
|
|
72
|
+
|
|
73
|
+
The **licensor** is the entity offering these terms, and the **software** is
|
|
74
|
+
the software the licensor makes available under these terms, including any
|
|
75
|
+
portion of it.
|
|
76
|
+
|
|
77
|
+
**you** refers to the individual or entity agreeing to these terms.
|
|
78
|
+
|
|
79
|
+
**your company** is any legal entity, sole proprietorship, or other kind of
|
|
80
|
+
organization that you work for, plus all organizations that have control
|
|
81
|
+
over, are under the control of, or are under common control with that
|
|
82
|
+
organization. **control** means ownership of substantially all the assets of
|
|
83
|
+
an entity, or the power to direct its management and policies by vote,
|
|
84
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
85
|
+
|
|
86
|
+
**your licenses** are all the licenses granted to you for the software under
|
|
87
|
+
these terms.
|
|
88
|
+
|
|
89
|
+
**use** means anything you do with the software requiring one of your
|
|
90
|
+
licenses.
|
|
91
|
+
|
|
92
|
+
**trademark** means trademarks, service marks, and similar rights.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
Copyright 2025-2026 En Dash Consulting
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @graview/ship
|
|
2
|
+
|
|
3
|
+
What **every** deployment of a Graview app needs, hosted or self-hosted: one `defineApp`
|
|
4
|
+
declaration plus one persistence adapter is a running deployment.
|
|
5
|
+
|
|
6
|
+
- **`openStore({ app, adapter })`** — load what was stored, migrate it forward, fold it into
|
|
7
|
+
a live `Store`, and keep the adapter current (every diff appends its operations and
|
|
8
|
+
rewrites the snapshot).
|
|
9
|
+
- **`createFileAdapter(root)`** — persistence a person can read: `snapshot.json`,
|
|
10
|
+
append-only `log.jsonl`, `meta.json` with the stored schema version. The core's sqlite
|
|
11
|
+
adapter is the scale answer; this is the "where is my data" answer.
|
|
12
|
+
- **`createBrowserAdapter()`** — the same three things in `localStorage`, for an app that
|
|
13
|
+
runs in the page with no server: the sample apps remember their edits through it,
|
|
14
|
+
attributed and undoable, migrations included. Import from `@graview/ship/browser` in a
|
|
15
|
+
bundle (the root entry carries the file adapter's `node:fs`). Conventions the helpers
|
|
16
|
+
read: `?fresh=1` returns to the seed (`openStore({ fresh })`), and a driven browser
|
|
17
|
+
starts fresh unless it says `?remember=1` — `browserStartsFresh()`, `forgetFreshParam()`.
|
|
18
|
+
- **The store reopens with its history.** `openStore` hands the persisted log to the
|
|
19
|
+
store alongside the snapshot, so what was done in an earlier session is still in the
|
|
20
|
+
activity and still undoable — persistence is the op log, not a cache of the graph.
|
|
21
|
+
- **Op-log-native migrations** — a declaration carries `version` and `migrations`
|
|
22
|
+
(`{ from, to, title, apply(snapshot) → primitives }`). Running one appends ordinary
|
|
23
|
+
operations: authored `system · ship:migration`, stating intent, carrying their inverse.
|
|
24
|
+
`graview check` refuses a chain with gaps or multi-version jumps before deploy time.
|
|
25
|
+
- **`exportBundle` / `assertBundle`** — the anti-lock-in shape: graph + attributed history +
|
|
26
|
+
version in one JSON bundle, re-importable into any deployment of the same declaration.
|
|
27
|
+
- **`health(store)`** — coherence, not liveness: dangling edges, standing, sizes.
|
|
28
|
+
- **`serveStore` / `openRemote`** — the store behind HTTP, and the other end of the wire. A
|
|
29
|
+
client sends CALLS, never primitives; the server applies them through an ordinary `Store`
|
|
30
|
+
under the seat the request carries, so the policy refuses on the server exactly what it
|
|
31
|
+
refuses in a browser. `graview serve <entry>` is the command.
|
|
32
|
+
- **Content moves as steps.** The step DSL (`stepsMigration`) has five content steps beside
|
|
33
|
+
the schema ones — `put-node`, `patch-node`, `drop-node`, `put-edge`, `drop-edge` — each
|
|
34
|
+
judged against the stored graph when it runs, so a default that is already there is not
|
|
35
|
+
put twice. `seedSteps(seed, live)` diffs a bootstrap seed against a live snapshot into
|
|
36
|
+
them; `applySteps(store, steps)` lands them as one logged, undoable operation authored
|
|
37
|
+
`system · ship:sync-seed`. `graview sync-seed <entry> --seed <file> --data <dir> [--apply]
|
|
38
|
+
[--prune]` is the command.
|
|
39
|
+
|
|
40
|
+
## The seed is read once
|
|
41
|
+
|
|
42
|
+
`seed` is what `openStore` puts in an EMPTY store — the first install, and never again.
|
|
43
|
+
A store that has been opened before keeps what it has, whatever the seed file now says;
|
|
44
|
+
that is the whole reason a person's edits survive a deploy. So a change to the default
|
|
45
|
+
content is not a reason to delete the store (`fresh` is a demo's way back to the example,
|
|
46
|
+
not a redesign tool): it is `graview sync-seed`, which says what would change and lands
|
|
47
|
+
only that, under undo.
|
|
48
|
+
|
|
49
|
+
## The wire
|
|
50
|
+
|
|
51
|
+
Every route `serveStore` answers is `WIRE`, exported from the package and pinned by a test,
|
|
52
|
+
so a host in front of it knows what it must keep answering for `openRemote`, `graview mcp
|
|
53
|
+
--remote-url` and `graview apply --remote-url` to work unchanged:
|
|
54
|
+
|
|
55
|
+
| Method | Path | Says |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| GET | `/graview/state` | the graph, the log and the stored version |
|
|
58
|
+
| POST | `/graview/ops` | calls in, the ops they produced out — or `undo`, batches to take back; 409 with the policy's sentence when refused |
|
|
59
|
+
| GET | `/graview/since?seq=N` | the ops appended after N — everyone else's |
|
|
60
|
+
| GET | `/graview/health` | ship's own report, plus where the data is |
|
|
61
|
+
| GET | `/graview/export` | the whole store as one bundle, the way out |
|
|
62
|
+
| POST | `/graview/here` | say where you are; answers with who else is, and the ops since `seq` |
|
|
63
|
+
| GET | `/graview/who` | who is here right now |
|
|
64
|
+
| POST | `/graview/leave` | say you have gone |
|
|
65
|
+
|
|
66
|
+
A request carries its seat in `x-graview-seat` and `x-graview-roles` (`SEAT_HEADERS`) by
|
|
67
|
+
default; `serveStore({ seatOf })` is where a host reads its own credential instead. Whatever
|
|
68
|
+
a host asks for rides along: `openRemote({ headers })` sends them with every request, and
|
|
69
|
+
the framework never reads them. `openRemote(...).settled()` resolves once every call sent
|
|
70
|
+
so far has been answered — a browser never waits for it; a host that must report the
|
|
71
|
+
server's verdict before it exits does.
|
|
72
|
+
|
|
73
|
+
## The hosted-store contract
|
|
74
|
+
|
|
75
|
+
A third party stands up their own host — a file store or SQLite, `graview serve`,
|
|
76
|
+
`graview mcp` — without forking anything here. Graview Cloud is the polished multi-tenant
|
|
77
|
+
host of the same API, and it consumes this package the way any customer would.
|
|
78
|
+
|
|
79
|
+
| Concern | In the framework | In a host (Graview Cloud, or yours) |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| Op log + snapshot + migrate on open | `openStore` | runs it on the server, per deployment |
|
|
82
|
+
| The wire | `serveStore`, `openRemote`, `WIRE` | production TLS, a gateway URL |
|
|
83
|
+
| Who is asking | `Principal` on every `apply`; `seatOf` reads the request | maps users, keys and agents to principals; tenancy; quotas |
|
|
84
|
+
| Seed | read once, on an empty store | the same |
|
|
85
|
+
| Default content moving | `seedSteps`, `applySteps`, `graview sync-seed` | when to run it, and for whom |
|
|
86
|
+
| An agent attaching | `graview mcp`, `graview apply`, `--remote-url`, `--header` | issuing the keys those headers carry |
|
|
87
|
+
| Schema moving | `version`, `migrations[]`, `graview check` | fleet upgrades |
|
|
88
|
+
|
|
89
|
+
## The boundary
|
|
90
|
+
|
|
91
|
+
Anything **one** deployment needs lives here. Anything only the **operator of many**
|
|
92
|
+
deployments needs — tenancy, provisioning, deploy-to-URL, billing, fleet upgrades, the
|
|
93
|
+
builder UX — lives in the `graview-cloud` repo, which consumes this package the way any
|
|
94
|
+
customer would. If Cloud ever needs a private hook into the framework, that hook is a
|
|
95
|
+
missing public seam to fix here first.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { PersistenceAdapter } from "@graview/core";
|
|
2
|
+
/**
|
|
3
|
+
* The slice of `Storage` this adapter needs — `localStorage` in a browser,
|
|
4
|
+
* a `Map` dressed as one in a test or a node rehearsal. Declared here rather
|
|
5
|
+
* than as the DOM's own type so the package needs no DOM lib to build.
|
|
6
|
+
*/
|
|
7
|
+
export interface StorageLike {
|
|
8
|
+
getItem(key: string): string | null;
|
|
9
|
+
setItem(key: string, value: string): void;
|
|
10
|
+
removeItem(key: string): void;
|
|
11
|
+
}
|
|
12
|
+
export interface BrowserAdapter extends PersistenceAdapter<string> {
|
|
13
|
+
loadMeta(scope: string): {
|
|
14
|
+
version: number;
|
|
15
|
+
} | null;
|
|
16
|
+
saveMeta(scope: string, meta: {
|
|
17
|
+
version: number;
|
|
18
|
+
}): void;
|
|
19
|
+
/** The storage keys this scope occupies — for a person or a test to look. */
|
|
20
|
+
keysFor(scope: string): {
|
|
21
|
+
snapshot: string;
|
|
22
|
+
log: string;
|
|
23
|
+
meta: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface BrowserAdapterOptions {
|
|
27
|
+
/** Defaults to the page's `localStorage`. */
|
|
28
|
+
readonly storage?: StorageLike;
|
|
29
|
+
/** Key prefix, so two apps on one origin do not read each other's graph. */
|
|
30
|
+
readonly prefix?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Persistence in the browser itself: the SAME three things the file adapter
|
|
34
|
+
* writes — the snapshot, the append-only log, the stored schema version —
|
|
35
|
+
* as three `localStorage` entries per scope. It slots into `openStore`
|
|
36
|
+
* unchanged, migrations included, so a sample app that remembers is the
|
|
37
|
+
* same lifecycle as a deployment that does, minus the server.
|
|
38
|
+
*
|
|
39
|
+
* `localStorage` is synchronous and small (a few megabytes an origin), which
|
|
40
|
+
* is exactly right for a demo or a single person's graph and exactly wrong
|
|
41
|
+
* for a shared deployment — that is what the file and sqlite adapters are
|
|
42
|
+
* for. If a log outgrows it the honest next step is IndexedDB behind this
|
|
43
|
+
* same interface, not a bigger string.
|
|
44
|
+
*
|
|
45
|
+
* A write that fails (quota, a locked-down browser) THROWS, and `openStore`
|
|
46
|
+
* reports it: an app that believes it remembered and did not is the worst
|
|
47
|
+
* quiet state, so nothing here swallows an error.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createBrowserAdapter(options?: BrowserAdapterOptions): BrowserAdapter;
|
|
50
|
+
/**
|
|
51
|
+
* Whether THIS load should start from the seed rather than from what the
|
|
52
|
+
* browser remembers.
|
|
53
|
+
*
|
|
54
|
+
* `?fresh=1` asks for it outright — the address a "start fresh" control
|
|
55
|
+
* navigates to. Beyond that, a DRIVEN browser starts fresh unless it says
|
|
56
|
+
* `?remember=1`: a harness is a specification of the example, and a
|
|
57
|
+
* harness whose second `goto` inherited its first one's edits would be
|
|
58
|
+
* testing its own residue. A person's browser is never driven, so a
|
|
59
|
+
* person always gets what they left.
|
|
60
|
+
*/
|
|
61
|
+
export declare function browserStartsFresh(location?: {
|
|
62
|
+
readonly search: string;
|
|
63
|
+
}, navigator?: {
|
|
64
|
+
readonly webdriver?: boolean;
|
|
65
|
+
}): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Drops `?fresh=1` from the address once it has been honoured, so the seed
|
|
68
|
+
* is the FIRST load rather than every load: a reload after starting fresh
|
|
69
|
+
* must keep what was done since, or "start fresh" is really "stop
|
|
70
|
+
* remembering".
|
|
71
|
+
*/
|
|
72
|
+
export declare function forgetFreshParam(win?: {
|
|
73
|
+
readonly location: {
|
|
74
|
+
readonly href: string;
|
|
75
|
+
};
|
|
76
|
+
readonly history: {
|
|
77
|
+
replaceState(data: unknown, unused: string, url: string): void;
|
|
78
|
+
};
|
|
79
|
+
}): void;
|
|
80
|
+
/** The address a "start fresh" control goes to: here, from the seed. */
|
|
81
|
+
export declare function freshHref(location?: {
|
|
82
|
+
readonly href: string;
|
|
83
|
+
}): string;
|
|
84
|
+
//# sourceMappingURL=browser-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-adapter.d.ts","sourceRoot":"","sources":["../src/browser-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnE;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAe,SAAQ,kBAAkB,CAAC,MAAM,CAAC;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,6EAA6E;IAC7E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzE;AAED,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CA4CxF;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,GAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,EACX,SAAS,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAE9B,GACV,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE;IACH,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE;QAAE,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAChE,GACtB,IAAI,CAKN;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CACvB,QAAQ,GAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,GACV,MAAM,CAIR"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence in the browser itself: the SAME three things the file adapter
|
|
3
|
+
* writes — the snapshot, the append-only log, the stored schema version —
|
|
4
|
+
* as three `localStorage` entries per scope. It slots into `openStore`
|
|
5
|
+
* unchanged, migrations included, so a sample app that remembers is the
|
|
6
|
+
* same lifecycle as a deployment that does, minus the server.
|
|
7
|
+
*
|
|
8
|
+
* `localStorage` is synchronous and small (a few megabytes an origin), which
|
|
9
|
+
* is exactly right for a demo or a single person's graph and exactly wrong
|
|
10
|
+
* for a shared deployment — that is what the file and sqlite adapters are
|
|
11
|
+
* for. If a log outgrows it the honest next step is IndexedDB behind this
|
|
12
|
+
* same interface, not a bigger string.
|
|
13
|
+
*
|
|
14
|
+
* A write that fails (quota, a locked-down browser) THROWS, and `openStore`
|
|
15
|
+
* reports it: an app that believes it remembered and did not is the worst
|
|
16
|
+
* quiet state, so nothing here swallows an error.
|
|
17
|
+
*/
|
|
18
|
+
export function createBrowserAdapter(options = {}) {
|
|
19
|
+
const prefix = options.prefix ?? "graview";
|
|
20
|
+
const storage = options.storage ?? pageStorage();
|
|
21
|
+
const keysFor = (scope) => ({
|
|
22
|
+
snapshot: `${prefix}:${scope}:snapshot`,
|
|
23
|
+
log: `${prefix}:${scope}:log`,
|
|
24
|
+
meta: `${prefix}:${scope}:meta`,
|
|
25
|
+
});
|
|
26
|
+
const read = (key) => {
|
|
27
|
+
const raw = storage.getItem(key);
|
|
28
|
+
return raw === null ? null : JSON.parse(raw);
|
|
29
|
+
};
|
|
30
|
+
const write = (key, value) => storage.setItem(key, JSON.stringify(value));
|
|
31
|
+
return {
|
|
32
|
+
name: "browser",
|
|
33
|
+
keysFor,
|
|
34
|
+
async load(scope) {
|
|
35
|
+
return read(keysFor(scope).snapshot);
|
|
36
|
+
},
|
|
37
|
+
async save(scope, snapshot) {
|
|
38
|
+
write(keysFor(scope).snapshot, snapshot);
|
|
39
|
+
},
|
|
40
|
+
async delete(scope) {
|
|
41
|
+
const keys = keysFor(scope);
|
|
42
|
+
storage.removeItem(keys.snapshot);
|
|
43
|
+
storage.removeItem(keys.log);
|
|
44
|
+
storage.removeItem(keys.meta);
|
|
45
|
+
},
|
|
46
|
+
async loadLog(scope) {
|
|
47
|
+
return read(keysFor(scope).log) ?? [];
|
|
48
|
+
},
|
|
49
|
+
async appendOps(scope, ops) {
|
|
50
|
+
if (ops.length === 0)
|
|
51
|
+
return;
|
|
52
|
+
const key = keysFor(scope).log;
|
|
53
|
+
write(key, [...(read(key) ?? []), ...ops]);
|
|
54
|
+
},
|
|
55
|
+
loadMeta(scope) {
|
|
56
|
+
return read(keysFor(scope).meta);
|
|
57
|
+
},
|
|
58
|
+
saveMeta(scope, meta) {
|
|
59
|
+
write(keysFor(scope).meta, meta);
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function pageStorage() {
|
|
64
|
+
const found = globalThis.localStorage;
|
|
65
|
+
if (!found) {
|
|
66
|
+
throw new Error("createBrowserAdapter: no localStorage here — pass `storage` (any object with " +
|
|
67
|
+
"getItem/setItem/removeItem) when running outside a browser.");
|
|
68
|
+
}
|
|
69
|
+
return found;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Whether THIS load should start from the seed rather than from what the
|
|
73
|
+
* browser remembers.
|
|
74
|
+
*
|
|
75
|
+
* `?fresh=1` asks for it outright — the address a "start fresh" control
|
|
76
|
+
* navigates to. Beyond that, a DRIVEN browser starts fresh unless it says
|
|
77
|
+
* `?remember=1`: a harness is a specification of the example, and a
|
|
78
|
+
* harness whose second `goto` inherited its first one's edits would be
|
|
79
|
+
* testing its own residue. A person's browser is never driven, so a
|
|
80
|
+
* person always gets what they left.
|
|
81
|
+
*/
|
|
82
|
+
export function browserStartsFresh(location = globalThis
|
|
83
|
+
.location, navigator = globalThis.navigator) {
|
|
84
|
+
const params = new URLSearchParams(location.search);
|
|
85
|
+
if (params.get("fresh") === "1")
|
|
86
|
+
return true;
|
|
87
|
+
if (params.get("remember") === "1")
|
|
88
|
+
return false;
|
|
89
|
+
return navigator?.webdriver === true;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Drops `?fresh=1` from the address once it has been honoured, so the seed
|
|
93
|
+
* is the FIRST load rather than every load: a reload after starting fresh
|
|
94
|
+
* must keep what was done since, or "start fresh" is really "stop
|
|
95
|
+
* remembering".
|
|
96
|
+
*/
|
|
97
|
+
export function forgetFreshParam(win = globalThis) {
|
|
98
|
+
const url = new URL(win.location.href);
|
|
99
|
+
if (url.searchParams.get("fresh") !== "1")
|
|
100
|
+
return;
|
|
101
|
+
url.searchParams.delete("fresh");
|
|
102
|
+
win.history.replaceState(null, "", url.toString());
|
|
103
|
+
}
|
|
104
|
+
/** The address a "start fresh" control goes to: here, from the seed. */
|
|
105
|
+
export function freshHref(location = globalThis
|
|
106
|
+
.location) {
|
|
107
|
+
const url = new URL(location.href);
|
|
108
|
+
url.searchParams.set("fresh", "1");
|
|
109
|
+
return url.toString();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=browser-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-adapter.js","sourceRoot":"","sources":["../src/browser-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser entry: everything in `@graview/ship` that does not need a
|
|
3
|
+
* filesystem. An app bundled for the page imports from here, so a bundler
|
|
4
|
+
* never meets `node:fs` through the file adapter.
|
|
5
|
+
*/
|
|
6
|
+
export { browserStartsFresh, createBrowserAdapter, forgetFreshParam, freshHref, } from "./browser-adapter.js";
|
|
7
|
+
export type { BrowserAdapter, BrowserAdapterOptions, StorageLike } from "./browser-adapter.js";
|
|
8
|
+
export { migrateSnapshot, pendingMigrations } from "./migrations.js";
|
|
9
|
+
export { primitivesFor, sayStep, stepsMigration } from "./steps.js";
|
|
10
|
+
export type { MigrationStep } from "./steps.js";
|
|
11
|
+
export type { MigrationRun } from "./migrations.js";
|
|
12
|
+
export { openStore } from "./open-store.js";
|
|
13
|
+
export type { OpenStoreOptions, OpenedStore } from "./open-store.js";
|
|
14
|
+
export { applyToSnapshot } from "./snapshot.js";
|
|
15
|
+
export type { GraphSnapshot } from "./snapshot.js";
|
|
16
|
+
export { assertBundle, exportBundle } from "./export.js";
|
|
17
|
+
export type { AppBundle } from "./export.js";
|
|
18
|
+
export { health } from "./health.js";
|
|
19
|
+
export type { HealthReport } from "./health.js";
|
|
20
|
+
export { openRemote } from "./remote.js";
|
|
21
|
+
export { createBroadcastPresence, presenceChannelName } from "./presence.js";
|
|
22
|
+
export type { BroadcastPresenceOptions, ChannelLike } from "./presence.js";
|
|
23
|
+
export type { RemoteOptions, RemoteStore } from "./remote.js";
|
|
24
|
+
export { assertPhotoFits, photosUsed, storageBytes, PhotoTooLarge, PHOTO_BUDGET_BYTES, PHOTO_MAX_BYTES, } from "./photos.js";
|
|
25
|
+
export type { PhotoBudget, PhotoField } from "./photos.js";
|
|
26
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7E,YAAY,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser entry: everything in `@graview/ship` that does not need a
|
|
3
|
+
* filesystem. An app bundled for the page imports from here, so a bundler
|
|
4
|
+
* never meets `node:fs` through the file adapter.
|
|
5
|
+
*/
|
|
6
|
+
export { browserStartsFresh, createBrowserAdapter, forgetFreshParam, freshHref, } from "./browser-adapter.js";
|
|
7
|
+
export { migrateSnapshot, pendingMigrations } from "./migrations.js";
|
|
8
|
+
export { primitivesFor, sayStep, stepsMigration } from "./steps.js";
|
|
9
|
+
export { openStore } from "./open-store.js";
|
|
10
|
+
export { applyToSnapshot } from "./snapshot.js";
|
|
11
|
+
export { assertBundle, exportBundle } from "./export.js";
|
|
12
|
+
export { health } from "./health.js";
|
|
13
|
+
export { openRemote } from "./remote.js";
|
|
14
|
+
export { createBroadcastPresence, presenceChannelName } from "./presence.js";
|
|
15
|
+
export { assertPhotoFits, photosUsed, storageBytes, PhotoTooLarge, PHOTO_BUDGET_BYTES, PHOTO_MAX_BYTES, } from "./photos.js";
|
|
16
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,eAAe,GAChB,MAAM,aAAa,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { PersistenceAdapter } from "@graview/core";
|
|
2
|
+
import type { GraphSnapshot } from "./snapshot.js";
|
|
3
|
+
/**
|
|
4
|
+
* `graview serve` — the store behind HTTP, and the data in a folder you can
|
|
5
|
+
* open.
|
|
6
|
+
*
|
|
7
|
+
* The file adapter is the default because the point of this command is the
|
|
8
|
+
* answer to "where is my data": a directory holding `snapshot.json`, a
|
|
9
|
+
* `log.jsonl` with one operation per line that a person can `grep`, and a
|
|
10
|
+
* `meta.json` carrying the stored version. `--sqlite` swaps the adapter and
|
|
11
|
+
* changes nothing else, which is the actual claim about adapters.
|
|
12
|
+
*/
|
|
13
|
+
export declare const SERVE_USAGE = " graview serve <entry> [--data <dir>] [--port <n>] [--seed <file>] [--sqlite <file>]\n Serves the app's store over HTTP. The op log is the wire: a client\n sends calls, the store judges them under the caller's own seat, and\n the ops come back. Data lives in <dir> (default ./data) as readable\n JSON, or in a SQLite file with --sqlite.\n\n graview sync-seed <entry> --seed <file> [--data <dir> | --sqlite <file>]\n [--apply] [--prune] [--json]\n Diffs the bootstrap seed against the live store and says, as content\n steps, what would bring the store in step with it: records put,\n fields patched, ties made. Prints and exits by default; --apply lands\n the steps as one logged, undoable operation; --prune also drops what\n the seed no longer has. The seed itself is only ever read at first\n install \u2014 this is how default content moves afterwards, in place of\n deleting the store.\n";
|
|
14
|
+
/** The same store, whichever command asked: parsed from the flags every store command shares. */
|
|
15
|
+
export declare const STORE_FLAGS = "--data <dir> (default ./data) | --sqlite <file>, and --seed <file> for a first install";
|
|
16
|
+
export declare function flag(argv: readonly string[], name: string): string | undefined;
|
|
17
|
+
export interface StoreBackend {
|
|
18
|
+
readonly adapter: PersistenceAdapter<string> & {
|
|
19
|
+
loadMeta?(scope: string): {
|
|
20
|
+
version: number;
|
|
21
|
+
} | null;
|
|
22
|
+
saveMeta?(scope: string, meta: {
|
|
23
|
+
version: number;
|
|
24
|
+
}): void;
|
|
25
|
+
};
|
|
26
|
+
/** Where the data is, in words a person can open. */
|
|
27
|
+
readonly where: string;
|
|
28
|
+
readonly seed?: GraphSnapshot;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* THE BACKEND FLAGS, PARSED ONCE. `serve`, `sync-seed`, `mcp` and `apply`
|
|
32
|
+
* all take the same store: a folder of readable JSON, or a SQLite file, and
|
|
33
|
+
* a seed for a first install. One parser, so the four commands cannot come
|
|
34
|
+
* to mean different things by the same words.
|
|
35
|
+
*/
|
|
36
|
+
export declare function backendFrom(argv: readonly string[], cwd?: string): Promise<StoreBackend>;
|
|
37
|
+
export declare function serve(argv: readonly string[]): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* `graview sync-seed` — default content moves without a wipe.
|
|
40
|
+
*
|
|
41
|
+
* Read-only unless `--apply` is said, because the steps are the product: a
|
|
42
|
+
* person or an agent reads what WOULD change and decides. Applying lands
|
|
43
|
+
* them through `applySteps`, which is `receive` on the open store — the
|
|
44
|
+
* adapter hears it like any change, the log carries it with its inverse,
|
|
45
|
+
* and undo is the ordinary undo.
|
|
46
|
+
*/
|
|
47
|
+
export declare function syncSeed(argv: readonly string[]): Promise<number>;
|
|
48
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAInD;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,q9BAevB,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,WAAW,2FAA2F,CAAC;AAEpH,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI9E;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAAG;QAC7C,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QACrD,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;KAC3D,CAAC;IACF,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAUrG;AAoBD,wBAAsB,KAAK,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBpE;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDvE"}
|