@enbox/api 0.3.1 → 0.4.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.
Files changed (102) hide show
  1. package/README.md +63 -0
  2. package/dist/browser.mjs +11 -28
  3. package/dist/browser.mjs.map +4 -4
  4. package/dist/esm/advanced.js +1 -1
  5. package/dist/esm/define-protocol.js +3 -3
  6. package/dist/esm/did-api.js +1 -1
  7. package/dist/esm/did-api.js.map +1 -1
  8. package/dist/esm/dwn-api.js +6 -6
  9. package/dist/esm/dwn-api.js.map +1 -1
  10. package/dist/esm/dwn-reader-api.js +2 -2
  11. package/dist/esm/enbox.js +205 -0
  12. package/dist/esm/enbox.js.map +1 -0
  13. package/dist/esm/index.js +16 -15
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/protocol.js +2 -2
  16. package/dist/esm/protocol.js.map +1 -1
  17. package/dist/esm/record-data.js +79 -5
  18. package/dist/esm/record-data.js.map +1 -1
  19. package/dist/esm/record.js +49 -10
  20. package/dist/esm/record.js.map +1 -1
  21. package/dist/esm/repository.js +7 -7
  22. package/dist/esm/repository.js.map +1 -1
  23. package/dist/esm/typed-enbox.js +583 -0
  24. package/dist/esm/typed-enbox.js.map +1 -0
  25. package/dist/esm/typed-live-query.js +1 -1
  26. package/dist/esm/typed-record.js +370 -46
  27. package/dist/esm/typed-record.js.map +1 -1
  28. package/dist/esm/utils.js +25 -0
  29. package/dist/esm/utils.js.map +1 -1
  30. package/dist/esm/vc-api.js.map +1 -1
  31. package/dist/types/advanced.d.ts +1 -1
  32. package/dist/types/define-protocol.d.ts +3 -3
  33. package/dist/types/did-api.d.ts +4 -4
  34. package/dist/types/did-api.d.ts.map +1 -1
  35. package/dist/types/dwn-api.d.ts +12 -7
  36. package/dist/types/dwn-api.d.ts.map +1 -1
  37. package/dist/types/dwn-reader-api.d.ts +2 -2
  38. package/dist/types/enbox.d.ts +202 -0
  39. package/dist/types/enbox.d.ts.map +1 -0
  40. package/dist/types/grant-revocation.d.ts +2 -2
  41. package/dist/types/grant-revocation.d.ts.map +1 -1
  42. package/dist/types/index.d.ts +16 -15
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/live-query.d.ts +2 -2
  45. package/dist/types/live-query.d.ts.map +1 -1
  46. package/dist/types/permission-grant.d.ts +2 -2
  47. package/dist/types/permission-grant.d.ts.map +1 -1
  48. package/dist/types/permission-request.d.ts +2 -2
  49. package/dist/types/permission-request.d.ts.map +1 -1
  50. package/dist/types/protocol-types.d.ts +2 -2
  51. package/dist/types/protocol.d.ts +7 -7
  52. package/dist/types/protocol.d.ts.map +1 -1
  53. package/dist/types/record-data.d.ts +17 -0
  54. package/dist/types/record-data.d.ts.map +1 -1
  55. package/dist/types/record.d.ts +24 -10
  56. package/dist/types/record.d.ts.map +1 -1
  57. package/dist/types/repository-types.d.ts +19 -11
  58. package/dist/types/repository-types.d.ts.map +1 -1
  59. package/dist/types/repository.d.ts +7 -7
  60. package/dist/types/repository.d.ts.map +1 -1
  61. package/dist/types/typed-enbox.d.ts +613 -0
  62. package/dist/types/typed-enbox.d.ts.map +1 -0
  63. package/dist/types/typed-live-query.d.ts +1 -1
  64. package/dist/types/typed-record.d.ts +427 -53
  65. package/dist/types/typed-record.d.ts.map +1 -1
  66. package/dist/types/utils.d.ts +23 -0
  67. package/dist/types/utils.d.ts.map +1 -1
  68. package/dist/types/vc-api.d.ts +3 -3
  69. package/dist/types/vc-api.d.ts.map +1 -1
  70. package/package.json +12 -11
  71. package/src/advanced.ts +1 -1
  72. package/src/define-protocol.ts +3 -3
  73. package/src/did-api.ts +5 -5
  74. package/src/dwn-api.ts +22 -17
  75. package/src/dwn-reader-api.ts +2 -2
  76. package/src/enbox.ts +281 -0
  77. package/src/grant-revocation.ts +3 -3
  78. package/src/index.ts +17 -16
  79. package/src/live-query.ts +2 -2
  80. package/src/permission-grant.ts +4 -4
  81. package/src/permission-request.ts +3 -3
  82. package/src/protocol-types.ts +2 -2
  83. package/src/protocol.ts +8 -8
  84. package/src/record-data.ts +86 -5
  85. package/src/record.ts +54 -13
  86. package/src/repository-types.ts +19 -7
  87. package/src/repository.ts +15 -15
  88. package/src/typed-enbox.ts +1169 -0
  89. package/src/typed-live-query.ts +1 -1
  90. package/src/typed-record.ts +431 -53
  91. package/src/utils.ts +27 -0
  92. package/src/vc-api.ts +4 -4
  93. package/dist/esm/typed-web5.js +0 -339
  94. package/dist/esm/typed-web5.js.map +0 -1
  95. package/dist/esm/web5.js +0 -410
  96. package/dist/esm/web5.js.map +0 -1
  97. package/dist/types/typed-web5.d.ts +0 -221
  98. package/dist/types/typed-web5.d.ts.map +0 -1
  99. package/dist/types/web5.d.ts +0 -346
  100. package/dist/types/web5.d.ts.map +0 -1
  101. package/src/typed-web5.ts +0 -598
  102. package/src/web5.ts +0 -754
@@ -0,0 +1,613 @@
1
+ /**
2
+ * A protocol-scoped API returned by {@link Enbox.using}.
3
+ *
4
+ * `TypedEnbox` is the **primary developer interface** for interacting with
5
+ * protocol-backed records. It auto-injects the protocol URI, protocolPath,
6
+ * and schema into every operation, and provides compile-time path
7
+ * autocompletion plus typed data payloads via the schema map.
8
+ *
9
+ * All record-returning methods wrap the underlying `Record` instances in
10
+ * {@link TypedRecord} so that type information flows through reads, queries,
11
+ * updates, and subscriptions without manual casts.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const social = enbox.using(SocialProtocol);
16
+ *
17
+ * // Install the protocol
18
+ * await social.configure();
19
+ *
20
+ * // Create — path and data type are checked at compile time
21
+ * const { record } = await social.records.create('thread', {
22
+ * data: { title: 'Hello World', body: '...' },
23
+ * });
24
+ * // record is TypedRecord<ThreadData>
25
+ *
26
+ * const data = await record.data.json(); // ThreadData — no cast needed
27
+ *
28
+ * // Query — protocol and protocolPath are auto-injected
29
+ * const { records } = await social.records.query('thread');
30
+ * // records is TypedRecord<ThreadData>[]
31
+ *
32
+ * // Subscribe — real-time changes via TypedLiveQuery
33
+ * const { liveQuery } = await social.records.subscribe('thread/reply');
34
+ * liveQuery.on('create', (record) => {
35
+ * // record is TypedRecord<ReplyData>
36
+ * });
37
+ * ```
38
+ */
39
+ import type { DwnApi } from './dwn-api.js';
40
+ import type { Protocol } from './protocol.js';
41
+ import type { DateSort, ProtocolDefinition, ProtocolType, RecordsFilter } from '@enbox/dwn-sdk-js';
42
+ import type { DwnPaginationCursor, DwnResponseStatus } from '@enbox/agent';
43
+ import type { ProtocolPaths, SchemaMap, TypedProtocol, TypeNameAtPath } from './protocol-types.js';
44
+ import { TypedLiveQuery } from './typed-live-query.js';
45
+ import { TypedRecord } from './typed-record.js';
46
+ /**
47
+ * Resolves the TypeScript data type for a given protocol path.
48
+ *
49
+ * If the schema map contains a mapping for the type name at the given path,
50
+ * that type is returned. Otherwise falls back to `unknown`.
51
+ */
52
+ export type DataForPath<_D extends ProtocolDefinition, M extends SchemaMap, Path extends string> = TypeNameAtPath<Path> extends keyof M ? M[TypeNameAtPath<Path>] : unknown;
53
+ /**
54
+ * Resolves the `ProtocolType` entry for a given protocol path.
55
+ */
56
+ type ProtocolTypeForPath<D extends ProtocolDefinition, Path extends string> = TypeNameAtPath<Path> extends keyof D['types'] ? D['types'][TypeNameAtPath<Path>] extends ProtocolType ? D['types'][TypeNameAtPath<Path>] : undefined : undefined;
57
+ /**
58
+ * Resolves a `dataFormat` string literal union for a path, or `string` if none.
59
+ */
60
+ type DataFormatForPath<D extends ProtocolDefinition, Path extends string> = ProtocolTypeForPath<D, Path> extends {
61
+ dataFormats: infer F;
62
+ } ? F extends readonly string[] ? F[number] : string : string;
63
+ /**
64
+ * Options for {@link TypedEnbox} `records.create()`.
65
+ *
66
+ * The `data` field is type-checked against the protocol's schema map for
67
+ * the given path, providing compile-time safety for record payloads.
68
+ *
69
+ * @typeParam D - The protocol definition type.
70
+ * @typeParam M - The schema map mapping type names to TypeScript types.
71
+ * @typeParam Path - The protocol path string literal.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * await proto.records.create('notebook/page', {
76
+ * data: { title: 'My Page', body: '...' }, // type-checked as PageData
77
+ * parentContextId: notebook.contextId, // link to parent
78
+ * tags: { category: 'draft' },
79
+ * });
80
+ * ```
81
+ */
82
+ export type TypedCreateRequest<D extends ProtocolDefinition, M extends SchemaMap, Path extends string> = {
83
+ /** The data payload. Type-checked against the schema map for the given path. */
84
+ data: DataForPath<D, M, Path>;
85
+ /**
86
+ * The context ID of the parent record.
87
+ *
88
+ * Required when creating a child record under a parent in a hierarchical
89
+ * protocol structure. Use the parent record's {@link TypedRecord.contextId | contextId}
90
+ * as this value.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * const { record: notebook } = await proto.records.create('notebook', {
95
+ * data: { name: 'My Notebook' },
96
+ * });
97
+ *
98
+ * // Create a page under the notebook
99
+ * await proto.records.create('notebook/page', {
100
+ * data: { title: 'Page 1' },
101
+ * parentContextId: notebook.contextId,
102
+ * });
103
+ * ```
104
+ */
105
+ parentContextId?: string;
106
+ /**
107
+ * Whether the record should be publicly published.
108
+ *
109
+ * Published records can be read by anyone without authorization.
110
+ */
111
+ published?: boolean;
112
+ /**
113
+ * ISO 8601 timestamp for when the record is considered published.
114
+ * Only meaningful when `published` is `true`.
115
+ */
116
+ datePublished?: string;
117
+ /**
118
+ * The DID of the intended recipient.
119
+ *
120
+ * Sets the recipient for permission-scoped records. The recipient may
121
+ * have special read/write permissions as defined by the protocol's
122
+ * `$actions` rules.
123
+ */
124
+ recipient?: string;
125
+ /**
126
+ * The protocol role under which to create this record.
127
+ *
128
+ * The DWN will verify that the author is authorized to write under
129
+ * this role per the protocol's `$actions` configuration.
130
+ */
131
+ protocolRole?: string;
132
+ /**
133
+ * The MIME type / data format for the record.
134
+ *
135
+ * If omitted, defaults to the first entry in the protocol type's
136
+ * `dataFormats` array (typically `'application/json'`).
137
+ */
138
+ dataFormat?: DataFormatForPath<D, Path>;
139
+ /**
140
+ * Key-value metadata tags to attach to the record.
141
+ *
142
+ * Tags are indexed by the DWN and can be used in query filters for
143
+ * efficient lookups. Values can be strings, numbers, booleans, or
144
+ * arrays of strings/numbers.
145
+ */
146
+ tags?: globalThis.Record<string, string | number | boolean | string[] | number[]>;
147
+ /**
148
+ * Whether to persist the record to the local DWN immediately.
149
+ *
150
+ * Defaults to `true`. Set to `false` to create the record in memory
151
+ * only — you can call {@link TypedRecord.store | record.store()} later.
152
+ */
153
+ store?: boolean;
154
+ /**
155
+ * Whether to auto-encrypt the record.
156
+ *
157
+ * If omitted, encryption follows the protocol definition. Set to `true`
158
+ * to force encryption or `false` to skip it.
159
+ */
160
+ encryption?: boolean;
161
+ };
162
+ /**
163
+ * Response from {@link TypedEnbox} `records.create()`.
164
+ *
165
+ * Uses a discriminated union so that TypeScript narrows `record` to
166
+ * `TypedRecord<T>` after a `status.code` check:
167
+ *
168
+ * ```ts
169
+ * const result = await proto.records.create('notebook', { data });
170
+ * if (result.record) {
171
+ * // TypeScript knows `record` is TypedRecord<NotebookData> here
172
+ * console.log(result.record.id);
173
+ * }
174
+ * ```
175
+ *
176
+ * @typeParam T - The data type of the created record.
177
+ */
178
+ export type TypedCreateResponse<T = unknown> = (DwnResponseStatus & {
179
+ record: TypedRecord<T>;
180
+ }) | (DwnResponseStatus & {
181
+ record: undefined;
182
+ });
183
+ /**
184
+ * Filter options for {@link TypedEnbox} `records.query()` and `records.subscribe()`.
185
+ *
186
+ * The `protocol`, `protocolPath`, and `schema` fields are automatically
187
+ * injected by {@link TypedEnbox} — you only need to supply additional
188
+ * filter criteria.
189
+ *
190
+ * Common filter fields inherited from `RecordsFilter`:
191
+ *
192
+ * - **`parentId`** — Filter by parent context ID. Despite the name, this
193
+ * filters on the parent record's **context ID** (i.e. pass
194
+ * `parent.contextId`, not `parent.id`). Use this to find child records
195
+ * under a specific parent in a hierarchical protocol.
196
+ * - **`recordId`** — Match a specific record by its unique ID.
197
+ * - **`recipient`** — Filter by recipient DID.
198
+ * - **`dataFormat`** — Filter by MIME type.
199
+ * - **`dateCreated`** — Range filter on creation date.
200
+ * - **`contextId`** — Filter by context ID directly.
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * // Find pages under a specific notebook
205
+ * const { records } = await proto.records.query('notebook/page', {
206
+ * filter: {
207
+ * parentId: notebook.contextId, // filters by parent's context ID
208
+ * tags: { status: 'published' },
209
+ * },
210
+ * });
211
+ * ```
212
+ */
213
+ export type TypedQueryFilter = Omit<RecordsFilter, 'protocol' | 'protocolPath' | 'schema'> & {
214
+ /**
215
+ * Filter records by tag values.
216
+ *
217
+ * Only records whose tags match **all** specified key-value pairs are
218
+ * returned. Array values match if the record's tag contains any of the
219
+ * specified values.
220
+ */
221
+ tags?: globalThis.Record<string, string | number | boolean | (string | number)[]>;
222
+ /** Alias for `parentId` — filters records by parent context ID. */
223
+ parentContextId?: string;
224
+ };
225
+ /**
226
+ * Options for {@link TypedEnbox} `records.query()`.
227
+ *
228
+ * All fields are optional — calling `query(path)` with no request object
229
+ * returns all records at that path.
230
+ *
231
+ * @example
232
+ * ```ts
233
+ * const { records, cursor } = await proto.records.query('notebook', {
234
+ * filter: { tags: { archived: false } },
235
+ * dateSort: DateSort.CreatedDescending,
236
+ * pagination: { limit: 25 },
237
+ * });
238
+ *
239
+ * // Paginate for more
240
+ * if (cursor) {
241
+ * const { records: next } = await proto.records.query('notebook', {
242
+ * pagination: { limit: 25, cursor },
243
+ * });
244
+ * }
245
+ * ```
246
+ */
247
+ export type TypedQueryRequest = {
248
+ /**
249
+ * A remote DWN DID to query from.
250
+ *
251
+ * When set, the query is sent to the specified DID's remote DWN instead
252
+ * of the local DWN.
253
+ */
254
+ from?: string;
255
+ /**
256
+ * Filter criteria for the query.
257
+ *
258
+ * The `protocol`, `protocolPath`, and `schema` fields are auto-injected.
259
+ * See {@link TypedQueryFilter} for available filter fields.
260
+ */
261
+ filter?: TypedQueryFilter;
262
+ /**
263
+ * Sort order for the returned records.
264
+ *
265
+ * Use `DateSort.CreatedAscending`, `DateSort.CreatedDescending`,
266
+ * `DateSort.PublishedAscending`, or `DateSort.PublishedDescending`.
267
+ */
268
+ dateSort?: DateSort;
269
+ /**
270
+ * Pagination options.
271
+ *
272
+ * - `limit` — Maximum number of records to return.
273
+ * - `cursor` — A pagination cursor from a previous query response to
274
+ * resume from where the last page left off.
275
+ */
276
+ pagination?: {
277
+ limit?: number;
278
+ cursor?: DwnPaginationCursor;
279
+ };
280
+ /**
281
+ * The protocol role under which to execute the query.
282
+ *
283
+ * Required when the protocol's `$actions` rules restrict read access
284
+ * to specific roles.
285
+ */
286
+ protocolRole?: string;
287
+ /**
288
+ * When `true`, automatically decrypts encrypted records in the results.
289
+ *
290
+ * If omitted, encrypted records are returned as-is (data accessors will
291
+ * return encrypted bytes).
292
+ */
293
+ encryption?: boolean;
294
+ };
295
+ /**
296
+ * Response from {@link TypedEnbox} `records.query()`.
297
+ *
298
+ * @typeParam T - The data type of the queried records.
299
+ */
300
+ export type TypedQueryResponse<T = unknown> = DwnResponseStatus & {
301
+ /**
302
+ * The matching records, each wrapped as {@link TypedRecord | TypedRecord<T>}.
303
+ *
304
+ * The array is empty if no records match the filter criteria.
305
+ */
306
+ records: TypedRecord<T>[];
307
+ /**
308
+ * A pagination cursor for fetching the next page of results.
309
+ *
310
+ * Pass this to a subsequent `query()` call's `pagination.cursor` to
311
+ * continue from where this page ended. `undefined` when there are no
312
+ * more results.
313
+ */
314
+ cursor?: DwnPaginationCursor;
315
+ };
316
+ /**
317
+ * Options for {@link TypedEnbox} `records.read()`.
318
+ *
319
+ * A `filter` is required to identify which record to read. The most common
320
+ * approach is to filter by `recordId`.
321
+ *
322
+ * @example
323
+ * ```ts
324
+ * // Read a specific record by ID
325
+ * const { record } = await proto.records.read('notebook', {
326
+ * filter: { recordId: notebookId },
327
+ * });
328
+ *
329
+ * // Read from a remote DWN
330
+ * const { record: remote } = await proto.records.read('notebook', {
331
+ * from: 'did:example:alice',
332
+ * filter: { recordId: notebookId },
333
+ * });
334
+ * ```
335
+ */
336
+ export type TypedReadRequest = {
337
+ /**
338
+ * A remote DWN DID to read from.
339
+ *
340
+ * When set, the read is performed against the specified DID's remote
341
+ * DWN instead of the local DWN.
342
+ */
343
+ from?: string;
344
+ /**
345
+ * Filter to identify the record to read.
346
+ *
347
+ * The `protocol`, `protocolPath`, and `schema` fields are auto-injected.
348
+ * Typically you filter by `recordId` to read a specific record. Other
349
+ * fields from `RecordsFilter` (like `contextId`, `parentId`, `recipient`)
350
+ * are also available.
351
+ */
352
+ filter: Omit<RecordsFilter, 'protocol' | 'protocolPath' | 'schema'> & {
353
+ /** Alias for `parentId` — filters records by parent context ID. */
354
+ parentContextId?: string;
355
+ };
356
+ /**
357
+ * When `true`, automatically decrypts the record if it is encrypted.
358
+ *
359
+ * If omitted, encrypted records are returned as-is.
360
+ */
361
+ encryption?: boolean;
362
+ };
363
+ /**
364
+ * Response from {@link TypedEnbox} `records.read()`.
365
+ *
366
+ * Uses a discriminated union so that TypeScript narrows `record` to
367
+ * `TypedRecord<T>` after a truthiness check:
368
+ *
369
+ * ```ts
370
+ * const result = await proto.records.read('notebook', { filter: { recordId } });
371
+ * if (result.record) {
372
+ * const data = await result.record.data.json(); // NotebookData
373
+ * }
374
+ * ```
375
+ *
376
+ * @typeParam T - The data type of the read record.
377
+ */
378
+ export type TypedReadResponse<T = unknown> = (DwnResponseStatus & {
379
+ record: TypedRecord<T>;
380
+ }) | (DwnResponseStatus & {
381
+ record: undefined;
382
+ });
383
+ /**
384
+ * Options for {@link TypedEnbox} `records.delete()`.
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * const { status } = await proto.records.delete('notebook', {
389
+ * recordId: notebook.id,
390
+ * });
391
+ * ```
392
+ */
393
+ export type TypedDeleteRequest = {
394
+ /**
395
+ * A remote DWN DID to delete from.
396
+ *
397
+ * When set, the delete is performed on the specified DID's remote DWN.
398
+ */
399
+ from?: string;
400
+ /**
401
+ * The unique `recordId` of the record to delete.
402
+ *
403
+ * Use {@link TypedRecord.id | record.id} to obtain this value.
404
+ */
405
+ recordId: string;
406
+ };
407
+ /**
408
+ * Options for {@link TypedEnbox} `records.subscribe()`.
409
+ *
410
+ * @example
411
+ * ```ts
412
+ * const { liveQuery } = await proto.records.subscribe('notebook/page', {
413
+ * filter: { parentId: notebook.contextId },
414
+ * });
415
+ *
416
+ * liveQuery.on('create', (record) => {
417
+ * console.log('New page:', await record.data.json());
418
+ * });
419
+ * ```
420
+ */
421
+ export type TypedSubscribeRequest = {
422
+ /**
423
+ * A remote DWN DID to subscribe to.
424
+ *
425
+ * When set, the subscription listens to the specified DID's remote DWN.
426
+ */
427
+ from?: string;
428
+ /**
429
+ * Filter criteria for the subscription.
430
+ *
431
+ * The `protocol`, `protocolPath`, and `schema` fields are auto-injected.
432
+ * See {@link TypedQueryFilter} for available filter fields.
433
+ */
434
+ filter?: TypedQueryFilter;
435
+ /**
436
+ * The protocol role under which to subscribe.
437
+ *
438
+ * Required when the protocol's `$actions` rules restrict read access
439
+ * to specific roles.
440
+ */
441
+ protocolRole?: string;
442
+ };
443
+ /**
444
+ * Response from {@link TypedEnbox} `records.subscribe()`.
445
+ *
446
+ * @typeParam T - The data type of records in the subscription.
447
+ */
448
+ export type TypedSubscribeResponse<T = unknown> = DwnResponseStatus & {
449
+ /**
450
+ * The typed live query instance for receiving real-time record changes.
451
+ *
452
+ * `undefined` if the subscription request failed (check `status.code`).
453
+ * When defined, use `liveQuery.on('create' | 'update' | 'delete', callback)`
454
+ * to react to changes. Call `liveQuery.close()` to stop the subscription.
455
+ */
456
+ liveQuery?: TypedLiveQuery<T>;
457
+ };
458
+ /**
459
+ * A protocol-scoped API that auto-injects `protocol`, `protocolPath`, and
460
+ * `schema` into every DWN operation.
461
+ *
462
+ * All record-returning methods wrap results in {@link TypedRecord} so that
463
+ * the data type `T` (resolved from the schema map) flows end-to-end — from
464
+ * write through read, query, update, and subscribe — without manual casts.
465
+ *
466
+ * Obtain an instance via `enbox.using(typedProtocol)`.
467
+ *
468
+ * @example
469
+ * ```ts
470
+ * const social = enbox.using(SocialProtocol);
471
+ *
472
+ * await social.configure();
473
+ *
474
+ * const { record } = await social.records.create('friend', {
475
+ * data: { did: 'did:example:alice', alias: 'Alice' },
476
+ * });
477
+ * const data = await record.data.json(); // FriendData — no cast
478
+ *
479
+ * const { records } = await social.records.query('friend', {
480
+ * filter: { tags: { did: 'did:example:alice' } },
481
+ * });
482
+ * for (const r of records) {
483
+ * const d = await r.data.json(); // FriendData
484
+ * }
485
+ * ```
486
+ */
487
+ export declare class TypedEnbox<D extends ProtocolDefinition = ProtocolDefinition, M extends SchemaMap = SchemaMap> {
488
+ /** @internal */
489
+ private _dwn;
490
+ /** @internal */
491
+ private _definition;
492
+ /** @internal */
493
+ private _configured;
494
+ /** @internal */
495
+ private _ensureReadyPromise;
496
+ /** @internal */
497
+ private _validPaths;
498
+ /** @internal */
499
+ private _records?;
500
+ /**
501
+ * @internal Create a new `TypedEnbox` instance. Use `enbox.using(protocol)` instead.
502
+ * @param dwn - The underlying DWN API instance.
503
+ * @param protocol - The typed protocol containing the definition and schema map.
504
+ */
505
+ constructor(dwn: DwnApi, protocol: TypedProtocol<D, M>);
506
+ /**
507
+ * The protocol URI string (e.g. `'https://example.com/social'`).
508
+ *
509
+ * This is the globally unique identifier for the protocol and is
510
+ * auto-injected into every record operation.
511
+ */
512
+ get protocol(): string;
513
+ /**
514
+ * The raw protocol definition object.
515
+ *
516
+ * Contains the full `protocol`, `types`, and `structure` that define
517
+ * the protocol's schema and permission rules.
518
+ */
519
+ get definition(): D;
520
+ /**
521
+ * Configures (installs) this protocol on the local DWN.
522
+ *
523
+ * If the protocol is already installed with an identical definition,
524
+ * this is a no-op and returns the existing protocol with status `200`.
525
+ * If the definition has changed (e.g. new types, modified structure),
526
+ * the protocol is re-configured with the updated definition and returns
527
+ * status `202`.
528
+ *
529
+ * **Must be called before any record operations.** Methods like
530
+ * `records.create()`, `records.query()`, etc. will throw if the protocol
531
+ * has not been configured.
532
+ *
533
+ * @param options - Optional configuration overrides.
534
+ * @param options.encryption - Whether to enable auto-encryption for the
535
+ * protocol. If omitted, follows the protocol definition defaults.
536
+ * @returns The DWN response status and the installed protocol object.
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * const proto = enbox.using(NotebookProtocol);
541
+ *
542
+ * const { status, protocol } = await proto.configure();
543
+ * console.log(status.code); // 202 (first install) or 200 (already installed)
544
+ *
545
+ * // Now you can use records.create(), records.query(), etc.
546
+ * ```
547
+ */
548
+ configure(options?: {
549
+ encryption?: boolean;
550
+ }): Promise<DwnResponseStatus & {
551
+ protocol?: Protocol;
552
+ }>;
553
+ /**
554
+ * Whether the protocol has been configured (installed) on the local DWN.
555
+ *
556
+ * Returns `true` after a successful call to {@link TypedEnbox.configure | configure()}.
557
+ * Record operations will throw if this is `false`.
558
+ */
559
+ get isConfigured(): boolean;
560
+ /**
561
+ * Validates that the path is recognized.
562
+ * Throws a descriptive error if the path is not a valid protocol path.
563
+ */
564
+ private _assertValidPath;
565
+ /**
566
+ * Ensures the protocol is configured before performing record operations.
567
+ *
568
+ * On first call, queries for an existing protocol installation:
569
+ * - If found with an identical definition → marks as configured.
570
+ * - If found with a different definition → marks as configured but warns
571
+ * that the local definition differs from the installed one.
572
+ * - If not found → installs the protocol via `protocols.configure()`.
573
+ *
574
+ * Concurrent calls are deduplicated via a shared Promise so the network
575
+ * call only happens once.
576
+ */
577
+ private _ensureReady;
578
+ /**
579
+ * Performs the one-time auto-configuration check. Called at most once;
580
+ * subsequent calls reuse the same Promise via `_ensureReadyPromise`.
581
+ */
582
+ private _autoConfigureOnce;
583
+ /**
584
+ * Protocol-scoped record operations.
585
+ *
586
+ * Every method auto-injects the `protocol`, `protocolPath`, and `schema`
587
+ * from the protocol definition — you never need to specify them manually.
588
+ * Path parameters provide **compile-time autocompletion** via
589
+ * `ProtocolPaths<D>`, and data types are resolved from the schema map.
590
+ *
591
+ * All methods return {@link TypedRecord} or {@link TypedLiveQuery} instances
592
+ * that carry the resolved data type from the schema map, providing
593
+ * end-to-end type safety.
594
+ *
595
+ * Available methods:
596
+ * - {@link TypedEnbox.records.create | create(path, request)} — Create a new record
597
+ * - {@link TypedEnbox.records.query | query(path, request?)} — Query records with filters
598
+ * - {@link TypedEnbox.records.read | read(path, request)} — Read a single record
599
+ * - {@link TypedEnbox.records.delete | delete(path, request)} — Delete a record by ID
600
+ * - {@link TypedEnbox.records.subscribe | subscribe(path, request?)} — Real-time subscription
601
+ */
602
+ get records(): {
603
+ create: <Path extends ProtocolPaths<D> & string>(path: Path, request: TypedCreateRequest<D, M, Path>) => Promise<TypedCreateResponse<DataForPath<D, M, Path>>>;
604
+ query: <Path extends ProtocolPaths<D> & string>(path: Path, request?: TypedQueryRequest) => Promise<TypedQueryResponse<DataForPath<D, M, Path>>>;
605
+ read: <Path extends ProtocolPaths<D> & string>(path: Path, request: TypedReadRequest) => Promise<TypedReadResponse<DataForPath<D, M, Path>>>;
606
+ delete: <Path extends ProtocolPaths<D> & string>(path: Path, request: TypedDeleteRequest) => Promise<DwnResponseStatus>;
607
+ subscribe: <Path extends ProtocolPaths<D> & string>(path: Path, request?: TypedSubscribeRequest) => Promise<TypedSubscribeResponse<DataForPath<D, M, Path>>>;
608
+ };
609
+ }
610
+ /** @deprecated Use {@link TypedEnbox} instead. Will be removed in a future version. */
611
+ export declare const TypedWeb5: typeof TypedEnbox;
612
+ export {};
613
+ //# sourceMappingURL=typed-enbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-enbox.d.ts","sourceRoot":"","sources":["../../src/typed-enbox.ts"],"names":[],"mappings":"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"}
@@ -47,7 +47,7 @@ export type TypedRecordChange<T> = {
47
47
  * A type-safe wrapper around {@link LiveQuery} that preserves the data type `T`
48
48
  * through the initial snapshot and all subsequent change events.
49
49
  *
50
- * Obtain instances through `TypedWeb5.records.subscribe()` — never construct
50
+ * Obtain instances through `TypedEnbox.records.subscribe()` — never construct
51
51
  * directly.
52
52
  */
53
53
  export declare class TypedLiveQuery<T> {