@bandeira-tech/b3nd-save 0.8.1
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 +21 -0
- package/esm/_dnt.shims.d.ts +2 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +57 -0
- package/esm/byte-entity-shim.d.ts +47 -0
- package/esm/byte-entity-shim.d.ts.map +1 -0
- package/esm/byte-entity-shim.js +138 -0
- package/esm/clients/mod.d.ts +15 -0
- package/esm/clients/mod.d.ts.map +1 -0
- package/esm/clients/mod.js +14 -0
- package/esm/clients/save-client.d.ts +87 -0
- package/esm/clients/save-client.d.ts.map +1 -0
- package/esm/clients/save-client.js +174 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/mod.d.ts +40 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/mod.js +31 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/client-console/client.d.ts +30 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/client-console/client.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/client-console/client.js +70 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encoding/encoding.d.ts +16 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encoding/encoding.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encoding/encoding.js +50 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encrypt/mod.d.ts +235 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encrypt/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encrypt/mod.js +619 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/functional-client/functional-client.d.ts +43 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/functional-client/functional-client.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/functional-client/functional-client.js +54 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/match-pattern/match-pattern.d.ts +47 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/match-pattern/match-pattern.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/match-pattern/match-pattern.js +134 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/decorators.d.ts +20 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/decorators.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/decorators.js +34 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/network.d.ts +46 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/network.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/network.js +131 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/peer.d.ts +27 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/peer.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/peer.js +25 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/flood.d.ts +59 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/flood.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/flood.js +188 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/path-vector.d.ts +35 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/path-vector.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/path-vector.js +57 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/tell-and-read.d.ts +117 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/tell-and-read.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/tell-and-read.js +125 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/types.d.ts +112 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/types.js +21 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.d.ts +35 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.js +106 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.d.ts +88 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.js +86 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.d.ts +83 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.js +115 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/hooks.d.ts +164 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/hooks.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/hooks.js +67 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/identity.d.ts +99 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/identity.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/identity.js +190 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/operation-handle.d.ts +185 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/operation-handle.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/operation-handle.js +103 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/reactions.d.ts +58 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/reactions.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/reactions.js +64 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/rig.d.ts +295 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/rig.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/rig.js +898 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/types.d.ts +167 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/types.js +5 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.d.ts +278 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.js +89 -0
- package/esm/dispatch.d.ts +35 -0
- package/esm/dispatch.d.ts.map +1 -0
- package/esm/dispatch.js +40 -0
- package/esm/elasticsearch/mod.d.ts +31 -0
- package/esm/elasticsearch/mod.d.ts.map +1 -0
- package/esm/elasticsearch/mod.js +8 -0
- package/esm/elasticsearch/store.d.ts +44 -0
- package/esm/elasticsearch/store.d.ts.map +1 -0
- package/esm/elasticsearch/store.js +213 -0
- package/esm/entity-store.d.ts +106 -0
- package/esm/entity-store.d.ts.map +1 -0
- package/esm/entity-store.js +46 -0
- package/esm/entity.d.ts +125 -0
- package/esm/entity.d.ts.map +1 -0
- package/esm/entity.js +66 -0
- package/esm/errors.d.ts +23 -0
- package/esm/errors.d.ts.map +1 -0
- package/esm/errors.js +25 -0
- package/esm/fs/mod.d.ts +28 -0
- package/esm/fs/mod.d.ts.map +1 -0
- package/esm/fs/mod.js +13 -0
- package/esm/fs/store.d.ts +45 -0
- package/esm/fs/store.d.ts.map +1 -0
- package/esm/fs/store.js +194 -0
- package/esm/indexeddb/mod.d.ts +9 -0
- package/esm/indexeddb/mod.d.ts.map +1 -0
- package/esm/indexeddb/mod.js +8 -0
- package/esm/indexeddb/store.d.ts +47 -0
- package/esm/indexeddb/store.d.ts.map +1 -0
- package/esm/indexeddb/store.js +299 -0
- package/esm/ipfs/mod.d.ts +24 -0
- package/esm/ipfs/mod.d.ts.map +1 -0
- package/esm/ipfs/mod.js +13 -0
- package/esm/ipfs/store.d.ts +42 -0
- package/esm/ipfs/store.d.ts.map +1 -0
- package/esm/ipfs/store.js +197 -0
- package/esm/localstorage/mod.d.ts +9 -0
- package/esm/localstorage/mod.d.ts.map +1 -0
- package/esm/localstorage/mod.js +8 -0
- package/esm/localstorage/store.d.ts +45 -0
- package/esm/localstorage/store.d.ts.map +1 -0
- package/esm/localstorage/store.js +147 -0
- package/esm/memory/mod.d.ts +12 -0
- package/esm/memory/mod.d.ts.map +1 -0
- package/esm/memory/mod.js +11 -0
- package/esm/memory/store.d.ts +73 -0
- package/esm/memory/store.d.ts.map +1 -0
- package/esm/memory/store.js +300 -0
- package/esm/mod.d.ts +36 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +31 -0
- package/esm/mongo/mod.d.ts +35 -0
- package/esm/mongo/mod.d.ts.map +1 -0
- package/esm/mongo/mod.js +8 -0
- package/esm/mongo/store.d.ts +42 -0
- package/esm/mongo/store.d.ts.map +1 -0
- package/esm/mongo/store.js +185 -0
- package/esm/package.json +3 -0
- package/esm/payload.d.ts +24 -0
- package/esm/payload.d.ts.map +1 -0
- package/esm/payload.js +30 -0
- package/esm/postgres/columns.d.ts +33 -0
- package/esm/postgres/columns.d.ts.map +1 -0
- package/esm/postgres/columns.js +51 -0
- package/esm/postgres/mod.d.ts +19 -0
- package/esm/postgres/mod.d.ts.map +1 -0
- package/esm/postgres/mod.js +9 -0
- package/esm/postgres/store.d.ts +75 -0
- package/esm/postgres/store.d.ts.map +1 -0
- package/esm/postgres/store.js +364 -0
- package/esm/read.d.ts +40 -0
- package/esm/read.d.ts.map +1 -0
- package/esm/read.js +67 -0
- package/esm/s3/mod.d.ts +23 -0
- package/esm/s3/mod.d.ts.map +1 -0
- package/esm/s3/mod.js +13 -0
- package/esm/s3/store.d.ts +46 -0
- package/esm/s3/store.d.ts.map +1 -0
- package/esm/s3/store.js +183 -0
- package/esm/sqlite/mod.d.ts +18 -0
- package/esm/sqlite/mod.d.ts.map +1 -0
- package/esm/sqlite/mod.js +8 -0
- package/esm/sqlite/schema.d.ts +10 -0
- package/esm/sqlite/schema.d.ts.map +1 -0
- package/esm/sqlite/schema.js +26 -0
- package/esm/sqlite/store.d.ts +42 -0
- package/esm/sqlite/store.d.ts.map +1 -0
- package/esm/sqlite/store.js +184 -0
- package/esm/types.d.ts +101 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/types.js +21 -0
- package/esm/url.d.ts +108 -0
- package/esm/url.d.ts.map +1 -0
- package/esm/url.js +151 -0
- package/package.json +93 -0
package/esm/types.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Store types for b3nd-save.
|
|
3
|
+
*
|
|
4
|
+
* The `Store` abstraction is internal to this package. `SaveClient`
|
|
5
|
+
* wraps a `Store` (or `EntityStore`) and exposes a
|
|
6
|
+
* `ProtocolInterfaceNode` to the rest of b3nd — outside the client,
|
|
7
|
+
* nothing else in the framework sees a `Store`.
|
|
8
|
+
*
|
|
9
|
+
* Stores are opaque byte storage: payloads are bytes in, bytes out.
|
|
10
|
+
* The payload type is the `Uint8Array | ReadableStream<Uint8Array>`
|
|
11
|
+
* union so callers and backends can avoid materializing large
|
|
12
|
+
* payloads when both sides know how to stream — same shape `fetch`
|
|
13
|
+
* already uses for request/response bodies. Backends that have no
|
|
14
|
+
* native streaming path collect the stream to bytes on write and
|
|
15
|
+
* return `Uint8Array` on read. Backends with native streaming
|
|
16
|
+
* (filesystem, S3, IPFS) keep streams end-to-end.
|
|
17
|
+
*
|
|
18
|
+
* Cross-cutting types (`Output`, `ProtocolInterfaceNode`,
|
|
19
|
+
* `DeleteResult`, `StatusResult`) still come from b3nd-core.
|
|
20
|
+
*/
|
|
21
|
+
import type { B3ndError, DeleteResult, Output, StatusResult } from "./deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.js";
|
|
22
|
+
/**
|
|
23
|
+
* Payload type accepted by `write` and produced by `read`.
|
|
24
|
+
*
|
|
25
|
+
* A backend may accept either shape on write and is free to return
|
|
26
|
+
* either shape on read — pick whichever avoids buffering when
|
|
27
|
+
* possible. Callers that always want bytes can collect with
|
|
28
|
+
* `new Response(payload).bytes()` or the equivalent helper.
|
|
29
|
+
*/
|
|
30
|
+
export type StorePayload = Uint8Array | ReadableStream<Uint8Array>;
|
|
31
|
+
/**
|
|
32
|
+
* Entry for a batch write operation.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* await store.write([
|
|
37
|
+
* { uri: "mutable://users/alice", payload: new TextEncoder().encode("alice") },
|
|
38
|
+
* ]);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export interface StoreEntry {
|
|
42
|
+
uri: string;
|
|
43
|
+
payload: StorePayload;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Per-entry result of a write operation.
|
|
47
|
+
*
|
|
48
|
+
* `errorDetail` mirrors `DeleteResult.errorDetail` — callers that want
|
|
49
|
+
* to react to specific failure modes (e.g. `STORAGE_ERROR` from the
|
|
50
|
+
* underlying driver vs. a programmer error from the store layer)
|
|
51
|
+
* should switch on `errorDetail.code` rather than parsing `error`.
|
|
52
|
+
* The `error` string remains for human-readable logs.
|
|
53
|
+
*/
|
|
54
|
+
export interface StoreWriteResult {
|
|
55
|
+
success: boolean;
|
|
56
|
+
error?: string;
|
|
57
|
+
errorDetail?: B3ndError;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Optional capability reporting for a Store.
|
|
61
|
+
*
|
|
62
|
+
* Backends declare what they can do so clients can make informed
|
|
63
|
+
* decisions (e.g., wrap deletes + writes in a transaction when
|
|
64
|
+
* `atomicBatch` is true).
|
|
65
|
+
*/
|
|
66
|
+
export interface StoreCapabilities {
|
|
67
|
+
/** Whether write + delete within a single call can be made atomic. */
|
|
68
|
+
atomicBatch?: boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Store — the batch-native byte-storage abstraction.
|
|
72
|
+
*
|
|
73
|
+
* Every operation takes arrays and returns per-item results. Each
|
|
74
|
+
* backend optimizes for its technology (Postgres → multi-row INSERT,
|
|
75
|
+
* S3 → parallel PutObject, etc.).
|
|
76
|
+
*
|
|
77
|
+
* The Store knows nothing about protocols, envelopes, message
|
|
78
|
+
* semantics, or content shape. Read returns `Output<StorePayload>`
|
|
79
|
+
* for `fn=read` and `fn=ls&format=full`; `fn=ls&format=uris` returns
|
|
80
|
+
* `string[]`, `fn=count` returns `number`.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* import { MemoryStore } from "@bandeira-tech/b3nd-save/memory";
|
|
85
|
+
* const store = new MemoryStore();
|
|
86
|
+
*
|
|
87
|
+
* await store.write([
|
|
88
|
+
* { uri: "mutable://app/config", payload: new TextEncoder().encode("dark") },
|
|
89
|
+
* ]);
|
|
90
|
+
* const [[uri, payload]] = await store.read(["mutable://app/config"]);
|
|
91
|
+
* const bytes = await new Response(payload as StorePayload).bytes();
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export interface Store {
|
|
95
|
+
write(entries: StoreEntry[]): Promise<StoreWriteResult[]>;
|
|
96
|
+
read<T = StorePayload>(urls: string[]): Promise<Output<T>[]>;
|
|
97
|
+
delete(uris: string[]): Promise<DeleteResult[]>;
|
|
98
|
+
status(): Promise<StatusResult>;
|
|
99
|
+
capabilities?(): StoreCapabilities;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,MAAM,EACN,YAAY,EACb,MAAM,kEAAkE,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,CAAC,GAAG,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAChD,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,YAAY,CAAC,IAAI,iBAAiB,CAAC;CACpC"}
|
package/esm/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Store types for b3nd-save.
|
|
3
|
+
*
|
|
4
|
+
* The `Store` abstraction is internal to this package. `SaveClient`
|
|
5
|
+
* wraps a `Store` (or `EntityStore`) and exposes a
|
|
6
|
+
* `ProtocolInterfaceNode` to the rest of b3nd — outside the client,
|
|
7
|
+
* nothing else in the framework sees a `Store`.
|
|
8
|
+
*
|
|
9
|
+
* Stores are opaque byte storage: payloads are bytes in, bytes out.
|
|
10
|
+
* The payload type is the `Uint8Array | ReadableStream<Uint8Array>`
|
|
11
|
+
* union so callers and backends can avoid materializing large
|
|
12
|
+
* payloads when both sides know how to stream — same shape `fetch`
|
|
13
|
+
* already uses for request/response bodies. Backends that have no
|
|
14
|
+
* native streaming path collect the stream to bytes on write and
|
|
15
|
+
* return `Uint8Array` on read. Backends with native streaming
|
|
16
|
+
* (filesystem, S3, IPFS) keep streams end-to-end.
|
|
17
|
+
*
|
|
18
|
+
* Cross-cutting types (`Output`, `ProtocolInterfaceNode`,
|
|
19
|
+
* `DeleteResult`, `StatusResult`) still come from b3nd-core.
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
package/esm/url.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Save-layer locator grammar — parsing and constructing the urls that
|
|
4
|
+
* stores in this package implement.
|
|
5
|
+
*
|
|
6
|
+
* This is **save's contract with its callers**, not a framework-wide
|
|
7
|
+
* standard. b3nd-core treats locators opaquely; it is each client's
|
|
8
|
+
* choice what grammar it accepts. Stores shipped by `@bandeira-tech/b3nd-save`
|
|
9
|
+
* (memory, postgres, mongo, sqlite, fs, ipfs, s3, elasticsearch,
|
|
10
|
+
* localstorage, indexeddb) honor the grammar defined here.
|
|
11
|
+
*
|
|
12
|
+
* A **url** = a uri (the canonical resource identifier) plus a query
|
|
13
|
+
* string of read parameters. The uri is the routing identity used for
|
|
14
|
+
* storage keys and observe-match keys. The query string carries
|
|
15
|
+
* request-time-only directives that shape the response without
|
|
16
|
+
* changing identity.
|
|
17
|
+
*
|
|
18
|
+
* Grammar:
|
|
19
|
+
*
|
|
20
|
+
* <uri>[?fn=<fn>][&<param>=<value>...][&x-<ns>.<key>=<value>...]
|
|
21
|
+
*
|
|
22
|
+
* Reserved `fn` values:
|
|
23
|
+
* - `read` — point read (default for non-trailing-slash uris)
|
|
24
|
+
* - `ls` — list under a prefix (default when uri ends with `/`)
|
|
25
|
+
* - `count` — count of entries under a prefix
|
|
26
|
+
* - `x-*.*` — provider-defined extension functions
|
|
27
|
+
*
|
|
28
|
+
* Standard params (meaningful only for some fns; stores ignore the rest):
|
|
29
|
+
* `limit`, `page`, `cursor`, `sortBy`, `sortOrder`, `pattern`, `format`.
|
|
30
|
+
*
|
|
31
|
+
* Anything matching `x-<ns>.<key>` lands in the `ext` map and is passed
|
|
32
|
+
* opaquely to the executing store. Callers inspect ext entries by
|
|
33
|
+
* their flat string key (e.g. `ext["x-feed.cursor"]`).
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Standard read parameters. All are optional; stores interpret the
|
|
37
|
+
* subset that makes sense for the requested fn and throw on the rest.
|
|
38
|
+
*/
|
|
39
|
+
export interface ReadParams {
|
|
40
|
+
limit?: number;
|
|
41
|
+
page?: number;
|
|
42
|
+
cursor?: string;
|
|
43
|
+
sortBy?: string;
|
|
44
|
+
sortOrder?: string;
|
|
45
|
+
pattern?: string;
|
|
46
|
+
format?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A parsed url decomposed into routing identity (`uri`), function
|
|
50
|
+
* (`fn`), standard read parameters (`params`), and the `x-*` extension
|
|
51
|
+
* bag (`ext`), plus the structural fields shared with WHATWG URL
|
|
52
|
+
* (`protocol`, `hostname`, `path`, `program`).
|
|
53
|
+
*/
|
|
54
|
+
export interface ParsedUrl {
|
|
55
|
+
/** Scheme without trailing `://` (e.g. `"mutable"`, `"b3nd"`). */
|
|
56
|
+
protocol: string;
|
|
57
|
+
/** Authority segment after `protocol://` (may be empty). */
|
|
58
|
+
hostname: string;
|
|
59
|
+
/** Everything after `protocol://<hostname>`. Empty or starts with `/`. */
|
|
60
|
+
path: string;
|
|
61
|
+
/** `protocol://hostname` — the routing root above the path. */
|
|
62
|
+
program: string;
|
|
63
|
+
/** Full routing identity: `program` + `path`. Query is stripped. */
|
|
64
|
+
uri: string;
|
|
65
|
+
/** Reserved fn (`read`/`ls`/`count`) or `x-<ns>.<name>` extension. */
|
|
66
|
+
fn: string;
|
|
67
|
+
/** Standard read params (numeric ones coerced). */
|
|
68
|
+
params: ReadParams;
|
|
69
|
+
/** Bag of `x-*` extension query params (every key starts with `x-`). */
|
|
70
|
+
ext: Record<string, string>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Parse a url into its structural fields, function, params, and extensions.
|
|
74
|
+
*
|
|
75
|
+
* Splitting rule: first `://` separates protocol from the rest; the first
|
|
76
|
+
* `/` in the rest separates hostname from path. Embedded `://` in the path
|
|
77
|
+
* (e.g. `b3nd://count/mutable://users/`) stays inside `path` — no
|
|
78
|
+
* special-casing.
|
|
79
|
+
*
|
|
80
|
+
* Defaults:
|
|
81
|
+
* - `fn=read` for uris without a trailing slash
|
|
82
|
+
* - `fn=ls` for uris with a trailing slash
|
|
83
|
+
*
|
|
84
|
+
* Numeric params (`limit`, `page`) are coerced; throws on NaN.
|
|
85
|
+
*/
|
|
86
|
+
export declare function parseUrl(url: string): ParsedUrl;
|
|
87
|
+
/**
|
|
88
|
+
* Serialize a parsed url back to its string form. Authoritative input is
|
|
89
|
+
* `uri`; structural fields (`protocol`/`hostname`/`path`/`program`) are
|
|
90
|
+
* ignored on serialization since `uri` already contains them.
|
|
91
|
+
*
|
|
92
|
+
* Omits `fn=` when it matches the trailing-slash default. Throws if any
|
|
93
|
+
* `ext` key does not start with `x-`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildUrl(parsed: {
|
|
96
|
+
uri: string;
|
|
97
|
+
fn?: string;
|
|
98
|
+
params?: ReadParams;
|
|
99
|
+
ext?: Record<string, string>;
|
|
100
|
+
}): string;
|
|
101
|
+
/**
|
|
102
|
+
* Canonical-uri portion of a save url. The query string is
|
|
103
|
+
* request-time-only and never participates in routing or storage
|
|
104
|
+
* keying. Cheap helper for stores and callers that need the bare uri
|
|
105
|
+
* without paying for full parse.
|
|
106
|
+
*/
|
|
107
|
+
export declare function uriOf(url: string): string;
|
|
108
|
+
//# sourceMappingURL=url.d.ts.map
|
package/esm/url.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,MAAM,EAAE,UAAU,CAAC;IACnB,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA8D/C;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GAAG,MAAM,CAwBT;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGzC"}
|
package/esm/url.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Save-layer locator grammar — parsing and constructing the urls that
|
|
4
|
+
* stores in this package implement.
|
|
5
|
+
*
|
|
6
|
+
* This is **save's contract with its callers**, not a framework-wide
|
|
7
|
+
* standard. b3nd-core treats locators opaquely; it is each client's
|
|
8
|
+
* choice what grammar it accepts. Stores shipped by `@bandeira-tech/b3nd-save`
|
|
9
|
+
* (memory, postgres, mongo, sqlite, fs, ipfs, s3, elasticsearch,
|
|
10
|
+
* localstorage, indexeddb) honor the grammar defined here.
|
|
11
|
+
*
|
|
12
|
+
* A **url** = a uri (the canonical resource identifier) plus a query
|
|
13
|
+
* string of read parameters. The uri is the routing identity used for
|
|
14
|
+
* storage keys and observe-match keys. The query string carries
|
|
15
|
+
* request-time-only directives that shape the response without
|
|
16
|
+
* changing identity.
|
|
17
|
+
*
|
|
18
|
+
* Grammar:
|
|
19
|
+
*
|
|
20
|
+
* <uri>[?fn=<fn>][&<param>=<value>...][&x-<ns>.<key>=<value>...]
|
|
21
|
+
*
|
|
22
|
+
* Reserved `fn` values:
|
|
23
|
+
* - `read` — point read (default for non-trailing-slash uris)
|
|
24
|
+
* - `ls` — list under a prefix (default when uri ends with `/`)
|
|
25
|
+
* - `count` — count of entries under a prefix
|
|
26
|
+
* - `x-*.*` — provider-defined extension functions
|
|
27
|
+
*
|
|
28
|
+
* Standard params (meaningful only for some fns; stores ignore the rest):
|
|
29
|
+
* `limit`, `page`, `cursor`, `sortBy`, `sortOrder`, `pattern`, `format`.
|
|
30
|
+
*
|
|
31
|
+
* Anything matching `x-<ns>.<key>` lands in the `ext` map and is passed
|
|
32
|
+
* opaquely to the executing store. Callers inspect ext entries by
|
|
33
|
+
* their flat string key (e.g. `ext["x-feed.cursor"]`).
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Parse a url into its structural fields, function, params, and extensions.
|
|
37
|
+
*
|
|
38
|
+
* Splitting rule: first `://` separates protocol from the rest; the first
|
|
39
|
+
* `/` in the rest separates hostname from path. Embedded `://` in the path
|
|
40
|
+
* (e.g. `b3nd://count/mutable://users/`) stays inside `path` — no
|
|
41
|
+
* special-casing.
|
|
42
|
+
*
|
|
43
|
+
* Defaults:
|
|
44
|
+
* - `fn=read` for uris without a trailing slash
|
|
45
|
+
* - `fn=ls` for uris with a trailing slash
|
|
46
|
+
*
|
|
47
|
+
* Numeric params (`limit`, `page`) are coerced; throws on NaN.
|
|
48
|
+
*/
|
|
49
|
+
export function parseUrl(url) {
|
|
50
|
+
const qIdx = url.indexOf("?");
|
|
51
|
+
const uri = qIdx < 0 ? url : url.slice(0, qIdx);
|
|
52
|
+
const query = qIdx < 0 ? "" : url.slice(qIdx + 1);
|
|
53
|
+
const schemeIdx = uri.indexOf("://");
|
|
54
|
+
let protocol = "";
|
|
55
|
+
let hostname = "";
|
|
56
|
+
let path = "";
|
|
57
|
+
if (schemeIdx >= 0) {
|
|
58
|
+
protocol = uri.slice(0, schemeIdx);
|
|
59
|
+
const rest = uri.slice(schemeIdx + 3);
|
|
60
|
+
const slash = rest.indexOf("/");
|
|
61
|
+
if (slash < 0) {
|
|
62
|
+
hostname = rest;
|
|
63
|
+
path = "";
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
hostname = rest.slice(0, slash);
|
|
67
|
+
path = rest.slice(slash);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
path = uri;
|
|
72
|
+
}
|
|
73
|
+
const program = protocol ? `${protocol}://${hostname}` : "";
|
|
74
|
+
const sp = new URLSearchParams(query);
|
|
75
|
+
const explicitFn = sp.get("fn") ?? undefined;
|
|
76
|
+
const defaultFn = uri.endsWith("/") ? "ls" : "read";
|
|
77
|
+
const fn = explicitFn ?? defaultFn;
|
|
78
|
+
const params = {};
|
|
79
|
+
const ext = {};
|
|
80
|
+
for (const [key, value] of sp.entries()) {
|
|
81
|
+
if (key === "fn")
|
|
82
|
+
continue;
|
|
83
|
+
if (key.startsWith("x-")) {
|
|
84
|
+
ext[key] = value;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
switch (key) {
|
|
88
|
+
case "limit":
|
|
89
|
+
case "page": {
|
|
90
|
+
const n = Number(value);
|
|
91
|
+
if (!Number.isFinite(n)) {
|
|
92
|
+
throw new Error(`Invalid ${key}: ${value}`);
|
|
93
|
+
}
|
|
94
|
+
params[key] = n;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case "cursor":
|
|
98
|
+
case "sortBy":
|
|
99
|
+
case "sortOrder":
|
|
100
|
+
case "pattern":
|
|
101
|
+
case "format":
|
|
102
|
+
params[key] = value;
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`Unknown read param: ${key}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { protocol, hostname, path, program, uri, fn, params, ext };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Serialize a parsed url back to its string form. Authoritative input is
|
|
112
|
+
* `uri`; structural fields (`protocol`/`hostname`/`path`/`program`) are
|
|
113
|
+
* ignored on serialization since `uri` already contains them.
|
|
114
|
+
*
|
|
115
|
+
* Omits `fn=` when it matches the trailing-slash default. Throws if any
|
|
116
|
+
* `ext` key does not start with `x-`.
|
|
117
|
+
*/
|
|
118
|
+
export function buildUrl(parsed) {
|
|
119
|
+
const { uri, fn, params, ext } = parsed;
|
|
120
|
+
const sp = new URLSearchParams();
|
|
121
|
+
const defaultFn = uri.endsWith("/") ? "ls" : "read";
|
|
122
|
+
if (fn && fn !== defaultFn)
|
|
123
|
+
sp.set("fn", fn);
|
|
124
|
+
if (params) {
|
|
125
|
+
for (const [k, v] of Object.entries(params)) {
|
|
126
|
+
if (v === undefined)
|
|
127
|
+
continue;
|
|
128
|
+
sp.set(k, String(v));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (ext) {
|
|
132
|
+
for (const [k, v] of Object.entries(ext)) {
|
|
133
|
+
if (!k.startsWith("x-")) {
|
|
134
|
+
throw new Error(`ext keys must start with 'x-': ${k}`);
|
|
135
|
+
}
|
|
136
|
+
sp.set(k, v);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const qs = sp.toString();
|
|
140
|
+
return qs ? `${uri}?${qs}` : uri;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Canonical-uri portion of a save url. The query string is
|
|
144
|
+
* request-time-only and never participates in routing or storage
|
|
145
|
+
* keying. Cheap helper for stores and callers that need the bare uri
|
|
146
|
+
* without paying for full parse.
|
|
147
|
+
*/
|
|
148
|
+
export function uriOf(url) {
|
|
149
|
+
const qIdx = url.indexOf("?");
|
|
150
|
+
return qIdx < 0 ? url : url.slice(0, qIdx);
|
|
151
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bandeira-tech/b3nd-save",
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "B3nd data-saving layer: Store backends (postgres, mongo, sqlite, fs, ipfs, s3, elasticsearch, localstorage, indexeddb, memory) and Store→ProtocolInterfaceNode clients.",
|
|
5
|
+
"homepage": "https://github.com/bandeira-tech/b3nd-save#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/bandeira-tech/b3nd-save.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/bandeira-tech/b3nd-save/issues"
|
|
13
|
+
},
|
|
14
|
+
"module": "./esm/mod.js",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./esm/mod.d.ts",
|
|
18
|
+
"import": "./esm/mod.js"
|
|
19
|
+
},
|
|
20
|
+
"./clients": {
|
|
21
|
+
"types": "./esm/clients/mod.d.ts",
|
|
22
|
+
"import": "./esm/clients/mod.js"
|
|
23
|
+
},
|
|
24
|
+
"./errors": {
|
|
25
|
+
"types": "./esm/errors.d.ts",
|
|
26
|
+
"import": "./esm/errors.js"
|
|
27
|
+
},
|
|
28
|
+
"./payload": {
|
|
29
|
+
"types": "./esm/payload.d.ts",
|
|
30
|
+
"import": "./esm/payload.js"
|
|
31
|
+
},
|
|
32
|
+
"./read": {
|
|
33
|
+
"types": "./esm/read.d.ts",
|
|
34
|
+
"import": "./esm/read.js"
|
|
35
|
+
},
|
|
36
|
+
"./dispatch": {
|
|
37
|
+
"types": "./esm/dispatch.d.ts",
|
|
38
|
+
"import": "./esm/dispatch.js"
|
|
39
|
+
},
|
|
40
|
+
"./memory": {
|
|
41
|
+
"types": "./esm/memory/mod.d.ts",
|
|
42
|
+
"import": "./esm/memory/mod.js"
|
|
43
|
+
},
|
|
44
|
+
"./postgres": {
|
|
45
|
+
"types": "./esm/postgres/mod.d.ts",
|
|
46
|
+
"import": "./esm/postgres/mod.js"
|
|
47
|
+
},
|
|
48
|
+
"./mongo": {
|
|
49
|
+
"types": "./esm/mongo/mod.d.ts",
|
|
50
|
+
"import": "./esm/mongo/mod.js"
|
|
51
|
+
},
|
|
52
|
+
"./sqlite": {
|
|
53
|
+
"types": "./esm/sqlite/mod.d.ts",
|
|
54
|
+
"import": "./esm/sqlite/mod.js"
|
|
55
|
+
},
|
|
56
|
+
"./fs": {
|
|
57
|
+
"types": "./esm/fs/mod.d.ts",
|
|
58
|
+
"import": "./esm/fs/mod.js"
|
|
59
|
+
},
|
|
60
|
+
"./ipfs": {
|
|
61
|
+
"types": "./esm/ipfs/mod.d.ts",
|
|
62
|
+
"import": "./esm/ipfs/mod.js"
|
|
63
|
+
},
|
|
64
|
+
"./s3": {
|
|
65
|
+
"types": "./esm/s3/mod.d.ts",
|
|
66
|
+
"import": "./esm/s3/mod.js"
|
|
67
|
+
},
|
|
68
|
+
"./elasticsearch": {
|
|
69
|
+
"types": "./esm/elasticsearch/mod.d.ts",
|
|
70
|
+
"import": "./esm/elasticsearch/mod.js"
|
|
71
|
+
},
|
|
72
|
+
"./localstorage": {
|
|
73
|
+
"types": "./esm/localstorage/mod.d.ts",
|
|
74
|
+
"import": "./esm/localstorage/mod.js"
|
|
75
|
+
},
|
|
76
|
+
"./indexeddb": {
|
|
77
|
+
"types": "./esm/indexeddb/mod.d.ts",
|
|
78
|
+
"import": "./esm/indexeddb/mod.js"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"scripts": {},
|
|
82
|
+
"engines": {
|
|
83
|
+
"node": ">=20"
|
|
84
|
+
},
|
|
85
|
+
"sideEffects": false,
|
|
86
|
+
"publishConfig": {
|
|
87
|
+
"access": "public"
|
|
88
|
+
},
|
|
89
|
+
"dependencies": {
|
|
90
|
+
"canonicalize": "2.0.0"
|
|
91
|
+
},
|
|
92
|
+
"_generatedBy": "dnt@dev"
|
|
93
|
+
}
|