graphddb 0.1.0 → 0.2.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/README.md +63 -9
- package/dist/{chunk-6LEHSX45.js → chunk-F27INYI2.js} +2839 -1081
- package/dist/cli.js +28 -5
- package/dist/index.d.ts +59 -3318
- package/dist/index.js +22 -1822
- package/dist/testing/index.d.ts +2 -2
- package/dist/types-D6qLpw2M.d.ts +4514 -0
- package/package.json +7 -2
- package/dist/types-CDrWiPxp.d.ts +0 -1203
package/README.md
CHANGED
|
@@ -217,11 +217,8 @@ The return type is inferred from `select`:
|
|
|
217
217
|
```ts
|
|
218
218
|
const result = await GroupMembership.list(
|
|
219
219
|
{ groupId: 'eng' },
|
|
220
|
-
{
|
|
221
|
-
|
|
222
|
-
limit: 20,
|
|
223
|
-
after: cursor,
|
|
224
|
-
},
|
|
220
|
+
{ userId: true, role: true },
|
|
221
|
+
{ limit: 20, after: cursor },
|
|
225
222
|
);
|
|
226
223
|
// result.items: GroupMembership[]
|
|
227
224
|
// result.cursor: string | null
|
|
@@ -238,8 +235,8 @@ logical groups. It is typed against the **full entity**, so it can reference att
|
|
|
238
235
|
```ts
|
|
239
236
|
const result = await Order.list(
|
|
240
237
|
{ userId: 'u001' },
|
|
238
|
+
{ orderId: true }, // amount / status need not be projected
|
|
241
239
|
{
|
|
242
|
-
select: { orderId: true }, // amount / status need not be projected
|
|
243
240
|
filter: {
|
|
244
241
|
status: 'confirmed', // #status = :v (equality shorthand)
|
|
245
242
|
amount: { gt: 100 }, // #amount > :v
|
|
@@ -283,23 +280,80 @@ the `KeyConditionExpression` / `ProjectionExpression`.
|
|
|
283
280
|
|
|
284
281
|
### Writes
|
|
285
282
|
|
|
283
|
+
Raw base-table writes are `putItem` / `updateItem` / `deleteItem` — the primitive
|
|
284
|
+
single-item operations with no lifecycle semantics:
|
|
285
|
+
|
|
286
286
|
```ts
|
|
287
|
-
await User.
|
|
287
|
+
await User.putItem({
|
|
288
288
|
userId: 'alice',
|
|
289
289
|
name: 'Alice',
|
|
290
290
|
email: 'alice@example.com',
|
|
291
291
|
status: 'active',
|
|
292
292
|
});
|
|
293
293
|
|
|
294
|
-
await GroupMembership.
|
|
294
|
+
await GroupMembership.putItem({
|
|
295
295
|
groupId: 'eng',
|
|
296
296
|
userId: 'alice',
|
|
297
297
|
role: 'admin',
|
|
298
298
|
});
|
|
299
299
|
|
|
300
|
-
await User.
|
|
300
|
+
await User.updateItem({ userId: 'alice' }, { status: 'disabled' });
|
|
301
301
|
```
|
|
302
302
|
|
|
303
|
+
Lifecycle-aware single writes — conditional gates, read-back, referential
|
|
304
|
+
effects — go through `DDBModel.mutate`, not the raw primitives (see
|
|
305
|
+
[The in-process unified envelope](#the-in-process-unified-envelope) below).
|
|
306
|
+
|
|
307
|
+
### The in-process unified envelope
|
|
308
|
+
|
|
309
|
+
`DDBModel.query` and `DDBModel.mutate` take a single **alias-map envelope** that
|
|
310
|
+
runs multiple routes in one call. This is the in-process analog of a GraphQL
|
|
311
|
+
operation: each alias is a named route, and the result is keyed by the same
|
|
312
|
+
aliases.
|
|
313
|
+
|
|
314
|
+
`DDBModel.query(map)` runs each read route independently and in parallel — there
|
|
315
|
+
is no cross-route consistency, exactly like GraphQL's parallel field resolution:
|
|
316
|
+
|
|
317
|
+
```ts
|
|
318
|
+
const { user, members } = await DDBModel.query({
|
|
319
|
+
user: { query: User, key: { userId: 'u1' }, select: { name: true } },
|
|
320
|
+
members: { list: GroupMembership, key: { groupId: 'eng' }, select: { role: true }, options: { limit: 20 } },
|
|
321
|
+
});
|
|
322
|
+
// user: Item | null ; members: { items, cursor }
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
A read route descriptor is `{ query | list: Model, key, select, options? }`
|
|
326
|
+
(exactly one of `query` / `list`). `options` for `query` is
|
|
327
|
+
`{ consistentRead?, maxDepth? }`; for `list` it is `{ limit?, after?, order?, filter? }`.
|
|
328
|
+
|
|
329
|
+
`DDBModel.mutate(map, { mode })` runs write routes. A write route descriptor is
|
|
330
|
+
`{ create | update | remove: Model, key, input?, condition?, result? }`:
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
const res = await DDBModel.mutate({
|
|
334
|
+
a: { create: GroupMembership, key: { groupId: 'eng', userId: 'u1' }, input: { role: 'admin' } },
|
|
335
|
+
b: { update: User, key: { userId: 'u1' }, input: { name: 'Ann' }, condition: { status: 'active' }, result: { select: { name: true } } },
|
|
336
|
+
}, { mode: 'transaction' });
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
- **`key`** is a single object or an **array of objects** (key-array bulk). A
|
|
340
|
+
transaction compiles to `TransactWriteItems`; parallel mode compiles to
|
|
341
|
+
`BatchWriteItem` (chunked, with `UnprocessedItems` retry).
|
|
342
|
+
- **`condition`** is an equality subset that gates the write.
|
|
343
|
+
- **`result: { select, options? }`** reads the written item back; omit it and the
|
|
344
|
+
route returns void.
|
|
345
|
+
- **`mode: 'transaction'`** (DEFAULT) is one atomic `TransactWriteItems`:
|
|
346
|
+
all-or-nothing rollback, throws on failure, and a map of more than 25 items
|
|
347
|
+
errors (it is never split). This is GraphQL's all-or-nothing atomic contract.
|
|
348
|
+
- **`mode: 'parallel'`** is non-atomic: each alias reports partial success in the
|
|
349
|
+
result object as `{ ok }` | `{ error }`, mirroring GraphQL's per-field partial
|
|
350
|
+
success. Independent ops run in parallel; dependencies are ordered by
|
|
351
|
+
`$.alias.field` references.
|
|
352
|
+
|
|
353
|
+
In GraphQL terms: a transaction is atomic all-or-nothing; parallel is non-atomic
|
|
354
|
+
per-field partial success; and `query` routes are parallel independent reads with
|
|
355
|
+
no cross-route consistency.
|
|
356
|
+
|
|
303
357
|
### Inspect Execution Plans
|
|
304
358
|
|
|
305
359
|
`explain()` shows the DynamoDB operations before they are executed.
|