qstd 0.2.27 → 0.3.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 CHANGED
@@ -20,6 +20,58 @@ A single npm package providing:
20
20
  pnpm add qstd
21
21
  ```
22
22
 
23
+ ## Prerequisites
24
+
25
+ ### TypeScript Configuration (Required)
26
+
27
+ To use subpath imports like `qstd/server`, `qstd/client`, or `qstd/react`, your `tsconfig.json` **must** use a modern module resolution strategy:
28
+
29
+ ```json
30
+ {
31
+ "compilerOptions": {
32
+ "moduleResolution": "bundler"
33
+ }
34
+ }
35
+ ```
36
+
37
+ **Valid options:** `"bundler"`, `"node16"`, or `"nodenext"`
38
+
39
+ #### Why is this required?
40
+
41
+ This package uses the **`exports`** field in `package.json` to define subpath exports:
42
+
43
+ ```json
44
+ {
45
+ "exports": {
46
+ "./react": { "types": "...", "import": "..." },
47
+ "./client": { "types": "...", "import": "..." },
48
+ "./server": { "types": "...", "import": "..." },
49
+ "./preset": { "types": "...", "import": "..." }
50
+ }
51
+ }
52
+ ```
53
+
54
+ The `exports` field is the modern Node.js way to define multiple entry points for a package. It allows a single package to expose different modules at different paths (e.g., `qstd/server` vs `qstd/client`) with proper type definitions for each.
55
+
56
+ **The problem:** The older `"moduleResolution": "node"` (also called "node10") setting predates the `exports` field and does not understand it. TypeScript will fail to resolve the types:
57
+
58
+ ```
59
+ Cannot find module 'qstd/server' or its corresponding type declarations.
60
+ There are types at '.../node_modules/qstd/dist/server/index.d.ts', but this result
61
+ could not be resolved under your current 'moduleResolution' setting.
62
+ ```
63
+
64
+ **The fix:** Use `"moduleResolution": "bundler"` which understands the `exports` field. This is the recommended setting for projects using modern bundlers like Vite, esbuild, or webpack 5+.
65
+
66
+ #### Quick Reference
67
+
68
+ | moduleResolution | Supports `exports` | Use Case |
69
+ |-----------------|-------------------|----------|
70
+ | `"node"` / `"node10"` | ❌ No | Legacy projects |
71
+ | `"node16"` | ✅ Yes | Node.js 16+ with ESM |
72
+ | `"nodenext"` | ✅ Yes | Latest Node.js features |
73
+ | `"bundler"` | ✅ Yes | **Recommended** for bundled apps |
74
+
23
75
  ## Usage
24
76
 
25
77
  ### React (Block + Hooks)
@@ -260,6 +260,7 @@ __export(time_exports, {
260
260
  formatThreadDateRange: () => formatThreadDateRange,
261
261
  now: () => now,
262
262
  sleep: () => sleep,
263
+ startTimer: () => startTimer,
263
264
  toMs: () => toMs
264
265
  });
265
266
  var formatDuration = (ms, options = {}) => {
@@ -454,6 +455,27 @@ var toMs = (value, unit = "seconds") => {
454
455
  };
455
456
  return value * multipliers[unit];
456
457
  };
458
+ function startTimer(options = {}) {
459
+ const start = Date.now();
460
+ const fmt = options.format ?? "ms";
461
+ const getElapsed = () => {
462
+ const elapsed = Date.now() - start;
463
+ if (fmt === "compact") {
464
+ const hours = Math.floor(elapsed / 36e5);
465
+ const minutes = Math.floor(elapsed % 36e5 / 6e4);
466
+ const seconds = Math.floor(elapsed % 6e4 / 1e3);
467
+ const milliseconds = elapsed % 1e3;
468
+ let result = "";
469
+ if (hours > 0) result += `${hours}h`;
470
+ if (minutes > 0) result += `${minutes}m`;
471
+ if (seconds > 0) result += `${seconds}s`;
472
+ if (milliseconds > 0 || result === "") result += `${milliseconds}ms`;
473
+ return result;
474
+ }
475
+ return elapsed;
476
+ };
477
+ return { stop: getElapsed, elapsed: getElapsed };
478
+ }
457
479
 
458
480
  // src/shared/flow.ts
459
481
  var flow_exports = {};
@@ -551,14 +573,9 @@ __export(log_exports, {
551
573
  info: () => info,
552
574
  label: () => label,
553
575
  log: () => log,
554
- startTimer: () => startTimer,
555
576
  warn: () => warn
556
577
  });
557
578
  var stringify = (value) => JSON.stringify(value, null, 2);
558
- var startTimer = () => {
559
- const start = Date.now();
560
- return () => Date.now() - start;
561
- };
562
579
  var log = (...values) => {
563
580
  console.log(...values.map(stringify));
564
581
  };
@@ -258,6 +258,7 @@ __export(time_exports, {
258
258
  formatThreadDateRange: () => formatThreadDateRange,
259
259
  now: () => now,
260
260
  sleep: () => sleep,
261
+ startTimer: () => startTimer,
261
262
  toMs: () => toMs
262
263
  });
263
264
  var formatDuration = (ms, options = {}) => {
@@ -452,6 +453,27 @@ var toMs = (value, unit = "seconds") => {
452
453
  };
453
454
  return value * multipliers[unit];
454
455
  };
456
+ function startTimer(options = {}) {
457
+ const start = Date.now();
458
+ const fmt = options.format ?? "ms";
459
+ const getElapsed = () => {
460
+ const elapsed = Date.now() - start;
461
+ if (fmt === "compact") {
462
+ const hours = Math.floor(elapsed / 36e5);
463
+ const minutes = Math.floor(elapsed % 36e5 / 6e4);
464
+ const seconds = Math.floor(elapsed % 6e4 / 1e3);
465
+ const milliseconds = elapsed % 1e3;
466
+ let result = "";
467
+ if (hours > 0) result += `${hours}h`;
468
+ if (minutes > 0) result += `${minutes}m`;
469
+ if (seconds > 0) result += `${seconds}s`;
470
+ if (milliseconds > 0 || result === "") result += `${milliseconds}ms`;
471
+ return result;
472
+ }
473
+ return elapsed;
474
+ };
475
+ return { stop: getElapsed, elapsed: getElapsed };
476
+ }
455
477
 
456
478
  // src/shared/flow.ts
457
479
  var flow_exports = {};
@@ -549,14 +571,9 @@ __export(log_exports, {
549
571
  info: () => info,
550
572
  label: () => label,
551
573
  log: () => log,
552
- startTimer: () => startTimer,
553
574
  warn: () => warn
554
575
  });
555
576
  var stringify = (value) => JSON.stringify(value, null, 2);
556
- var startTimer = () => {
557
- const start = Date.now();
558
- return () => Date.now() - start;
559
- };
560
577
  var log = (...values) => {
561
578
  console.log(...values.map(stringify));
562
579
  };
@@ -0,0 +1,257 @@
1
+ import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
2
+ import * as _t from "./types";
3
+ export type Client = ReturnType<typeof create>;
4
+ export declare const create: (props?: {
5
+ credentials?: _t.Credentials;
6
+ tableName: string;
7
+ }) => {
8
+ client: DynamoDBDocumentClient;
9
+ tableName: string | undefined;
10
+ };
11
+ /**
12
+ * Query or Scan DynamoDB with type-safe filters and modern API
13
+ * @param ddb - DynamoDB client
14
+ * @param props - Query/Scan properties
15
+ * @returns Items array by default; use `first` and `raw` flags to customize
16
+ *
17
+ * @example
18
+ * // Get items array (default)
19
+ * const items = await find<User>(doc, {
20
+ * tableName: 'users',
21
+ * pk: { value: 'user#123' }
22
+ * });
23
+ * // items: User[]
24
+ *
25
+ * @example
26
+ * // Get first item
27
+ * const user = await find<User>(doc, {
28
+ * tableName: 'users',
29
+ * pk: { value: 'user#123' },
30
+ * first: true,
31
+ * }); // user: User | undefined
32
+ *
33
+ * @example
34
+ * // Get full response with metadata
35
+ * const result = await find<User>(doc, {
36
+ * tableName: 'users',
37
+ * pk: { value: 'user#123' },
38
+ * raw: true,
39
+ * }); // result: RawResponse<User>
40
+ *
41
+ * @example
42
+ * // Type-safe filters with modern API
43
+ * const active = await find<User>(doc, {
44
+ * tableName: 'users',
45
+ * pk: { value: 'org#456' },
46
+ * sk: { op: 'begins_with', value: 'user#' },
47
+ * filters: [
48
+ * { key: 'status', op: '=', value: 'active' },
49
+ * { key: 'score', op: '>', value: 80 },
50
+ * { key: 'email', op: 'attribute_exists' }
51
+ * ],
52
+ * sort: 'desc',
53
+ * strong: true,
54
+ * }); // active: User[]
55
+ *
56
+ * @example
57
+ * // Scan mode - no pk/sk required, can filter on any attribute
58
+ * const allActive = await find<User>(doc, {
59
+ * tableName: 'users',
60
+ * scan: true,
61
+ * filters: [
62
+ * { key: 'pk', op: 'begins_with', value: 'user#' },
63
+ * { key: 'status', op: '=', value: 'active' },
64
+ * ],
65
+ * recursive: true,
66
+ * maxItems: 1000,
67
+ * }); // allActive: User[]
68
+ */
69
+ export declare function find<T extends object = Record<string, unknown>>(ddb: Client, props: _t.FindProps<T> & {
70
+ first: true;
71
+ raw: true;
72
+ }): Promise<{
73
+ item: T | undefined;
74
+ count: number;
75
+ scannedCount: number;
76
+ }>;
77
+ export declare function find<T extends object = Record<string, unknown>>(ddb: Client, props: _t.FindProps<T> & {
78
+ raw: true;
79
+ }): Promise<_t.RawResponse<T>>;
80
+ export declare function find<T extends object = Record<string, unknown>>(ddb: Client, props: _t.FindProps<T> & {
81
+ /** Return the first item from the items array */ first: true;
82
+ }): Promise<T | undefined>;
83
+ export declare function find<T extends object = Record<string, unknown>>(ddb: Client, props: _t.FindProps<T>): Promise<T[]>;
84
+ export declare const remove: (ddb: Client, props: {
85
+ key: _t.Key;
86
+ tableName?: string;
87
+ }) => Promise<import("@aws-sdk/lib-dynamodb").DeleteCommandOutput>;
88
+ /** * Create or overwrite an item
89
+ * @param ddb
90
+ * @param item
91
+ * @param opts
92
+ * @returns
93
+ */
94
+ export declare const save: <T extends object>(ddb: Client, props: {
95
+ tableName?: string;
96
+ item: T;
97
+ }) => Promise<import("@aws-sdk/lib-dynamodb").PutCommandOutput>;
98
+ /**
99
+ * Batch get multiple items from DynamoDB
100
+ *
101
+ * ## Limits
102
+ * - Max items per request: 100
103
+ * - Max request size: 16MB
104
+ * - Read capacity: 0.5 RCU per item (eventually consistent), 1 RCU (strongly consistent)
105
+ *
106
+ * @example
107
+ * const result = await batchGet(ddb, {
108
+ * tableName: 'users',
109
+ * keys: [{ pk: 'user#1', sk: 'profile' }, { pk: 'user#2', sk: 'profile' }]
110
+ * });
111
+ * console.log(`Retrieved: ${result.count}, Missing: ${result.missing}`);
112
+ * const users = result.items;
113
+ */
114
+ export declare function batchGet<T extends Record<string, unknown>>(ddb: Client, props: {
115
+ tableName: string;
116
+ keys: {
117
+ pk: string;
118
+ sk?: string;
119
+ }[];
120
+ maxRetries?: number;
121
+ strong?: boolean;
122
+ }): Promise<_t.BatchGetResult<T>>;
123
+ /**
124
+ * Batch write (put) multiple items to DynamoDB
125
+ *
126
+ * ## Operation Mode
127
+ * - **Without conditions**: Uses BatchWriteCommand (cheaper, faster)
128
+ * - Max items: 25 per request
129
+ * - Max size: 16MB per request
130
+ * - Cost: 1 WCU per item
131
+ * - Not atomic
132
+ *
133
+ * - **With conditions**: Auto-switches to TransactWriteCommand (atomic, safer)
134
+ * - Max items: 100 per request (4x better!)
135
+ * - Max size: 4MB per request
136
+ * - Cost: 2 WCU per item (2x more expensive)
137
+ * - Atomic: all succeed or all fail
138
+ *
139
+ * @example
140
+ * // Simple usage
141
+ * const result = await batchWrite(ddb, {
142
+ * tableName: 'users',
143
+ * items: [
144
+ * { item: { pk: 'user#1', sk: 'profile', name: 'Alice' } },
145
+ * { item: { pk: 'user#2', sk: 'profile', name: 'Bob' } }
146
+ * ]
147
+ * });
148
+ * console.log(`Processed: ${result.processed}, Failed: ${result.failed}`);
149
+ *
150
+ * @example
151
+ * // With transform - avoid manual mapping
152
+ * const result = await batchWrite(ddb, {
153
+ * tableName: 'users',
154
+ * items: users,
155
+ * transform: (user) => ({ item: user })
156
+ * });
157
+ *
158
+ * @example
159
+ * // With conditions (auto-switches to transact)
160
+ * const result = await batchWrite(ddb, {
161
+ * tableName: 'users',
162
+ * items: [
163
+ * { item: user1, cond: 'attribute_not_exists(pk)' },
164
+ * { item: user2, cond: 'version = :v1' }
165
+ * ]
166
+ * });
167
+ */
168
+ export declare function batchWrite<T extends Record<string, unknown>>(ddb: Client, props: {
169
+ tableName: string;
170
+ items: {
171
+ item: T;
172
+ cond?: string;
173
+ }[];
174
+ maxRetries?: number;
175
+ }): Promise<_t.BatchWriteResult>;
176
+ export declare function batchWrite<T extends Record<string, unknown>, I>(ddb: Client, props: {
177
+ tableName: string;
178
+ items: I[];
179
+ transform: (item: I) => {
180
+ item: T;
181
+ cond?: string;
182
+ };
183
+ maxRetries?: number;
184
+ }): Promise<_t.BatchWriteResult>;
185
+ /**
186
+ * Batch delete multiple items from DynamoDB
187
+ *
188
+ * ## Operation Mode
189
+ * - **Without conditions**: Uses BatchWriteCommand (cheaper, faster)
190
+ * - Max items: 25 per request
191
+ * - Max size: 16MB per request
192
+ * - Cost: 1 WCU per item
193
+ * - Not atomic
194
+ *
195
+ * - **With conditions**: Auto-switches to TransactWriteCommand (atomic, safer)
196
+ * - Max items: 100 per request (4x better!)
197
+ * - Max size: 4MB per request
198
+ * - Cost: 2 WCU per item (2x more expensive)
199
+ * - Atomic: all succeed or all fail
200
+ *
201
+ * @example
202
+ * const result = await batchDelete(ddb, {
203
+ * tableName: 'users',
204
+ * keys: [
205
+ * { key: { pk: 'user#1', sk: 'profile' } },
206
+ * { key: { pk: 'user#2', sk: 'profile' } }
207
+ * ]
208
+ * });
209
+ *
210
+ * console.log(`Deleted: ${result.processed}, Failed: ${result.failed}`);
211
+ *
212
+ * @example
213
+ * // With transform - avoid manual mapping
214
+ * const result = await batchDelete(ddb, {
215
+ * tableName: 'users',
216
+ * keys: [{ pk: 'user#1', sk: 'profile' }, { pk: 'user#2', sk: 'profile' }],
217
+ * transform: (key) => ({ key })
218
+ * });
219
+ *
220
+ * @example
221
+ * // With conditions (auto-switches to transact)
222
+ * const result = await batchDelete(ddb, {
223
+ * tableName: 'users',
224
+ * keys: [
225
+ * { key: { pk: 'user#1', sk: 'profile' }, cond: 'attribute_exists(pk)' },
226
+ * { key: { pk: 'user#2', sk: 'profile' }, cond: 'version = :v1' }
227
+ * ]
228
+ * });
229
+ */
230
+ export declare function batchDelete(ddb: Client, props: {
231
+ tableName: string;
232
+ keys: Array<{
233
+ key: _t.Key;
234
+ cond?: string;
235
+ }>;
236
+ maxRetries?: number;
237
+ }): Promise<_t.BatchDeleteResult>;
238
+ export declare function batchDelete<I>(ddb: Client, props: {
239
+ tableName: string;
240
+ keys: I[];
241
+ transform: (item: I) => {
242
+ key: _t.Key;
243
+ cond?: string;
244
+ };
245
+ maxRetries?: number;
246
+ }): Promise<_t.BatchDeleteResult>;
247
+ export declare const deleteTable: (ddb: Client, tableName: string) => Promise<import("@aws-sdk/client-dynamodb").DeleteTableCommandOutput>;
248
+ /**
249
+ * Check if a dynamodb table exists.
250
+ * @param doc
251
+ * @param TableName
252
+ * @returns
253
+ */
254
+ export declare const tableExists: (ddb: Client, props: {
255
+ tableName: string;
256
+ }) => Promise<boolean>;
257
+ //# sourceMappingURL=domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/ddb/domain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { NativeAttributeValue } from "@aws-sdk/lib-dynamodb";
2
+ import * as _t from "./types";
3
+ export declare const validateFindProps: <T extends object = Record<string, unknown>>(props: _t.FindProps<T> & {
4
+ first?: boolean;
5
+ raw?: boolean;
6
+ }) => void;
7
+ export declare const buildKeyConditionExpression: (pk: {
8
+ key?: string;
9
+ value: string;
10
+ }, sk: _t.SkCond | undefined, names: Record<string, string>, values: Record<string, NativeAttributeValue>) => string;
11
+ export declare const buildFilterExpression: <T extends object>(filters: ReadonlyArray<_t.FilterClause<T>>, names: Record<string, string>, values: Record<string, NativeAttributeValue>) => string | undefined;
12
+ export declare const buildProjectionExpression: <T>(projection: (keyof T)[], names: Record<string, string>) => string;
13
+ /**
14
+ * Sleep for exponential backoff
15
+ */
16
+ export declare const sleep: (ms: number) => Promise<unknown>;
17
+ /**
18
+ * Calculate backoff delay for retries
19
+ */
20
+ export declare const backoffDelay: (attempt: number) => number;
21
+ /**
22
+ * Chunk an array into smaller arrays of specified size
23
+ */
24
+ export declare const chunk: <T>(arr: T[], size: number) => T[][];
25
+ //# sourceMappingURL=fns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fns.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/ddb/fns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,SA6B5D,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,IAAI;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACnC,IAAI,EAAE,CAAC,MAAM,GAAG,SAAS,EACzB,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,QAAQ,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,WAoD7C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,MAAM,EACpD,SAAS,aAAa,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAC1C,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,QAAQ,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,uBAoE7C,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,CAAC,EACzC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,EACvB,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,WAQ9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,qBACmB,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAE9C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,MAAM,KAAG,CAAC,EAAE,EAIpD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./domain";
2
+ export * from "./literals";
3
+ export type { Key } from "./types";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/ddb/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * these 2 lsis should solve all future lsis. Lsi can be a
3
+ * generic type that has different sk based on the pk.
4
+ * E.g. pkUser can store username in lsi and pkDocument
5
+ * can store id. By lsi being a generic field, can serve
6
+ * the role of multiple lsis.
7
+ */
8
+ export declare const lsi: {
9
+ readonly name: "lsi";
10
+ readonly sk: "lsi";
11
+ };
12
+ export declare const lsi2: {
13
+ readonly name: "lsi2";
14
+ readonly sk: "lsi2";
15
+ };
16
+ export declare const lsiUsername: {
17
+ readonly name: "username-lsi";
18
+ readonly sk: "username";
19
+ };
20
+ export declare const lsiNormalized: {
21
+ /** use in index_name */
22
+ readonly name: "normalized-lsi";
23
+ readonly sk: "normalized";
24
+ };
25
+ export declare const lsiPhash: {
26
+ /** use in index_name */
27
+ readonly name: "phash-lsi";
28
+ readonly sk: "phash";
29
+ };
30
+ //# sourceMappingURL=literals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"literals.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/ddb/literals.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,GAAG;;;CAAsC,CAAC;AACvD,eAAO,MAAM,IAAI;;;CAAwC,CAAC;AAE1D,eAAO,MAAM,WAAW;;;CAGd,CAAC;AAGX,eAAO,MAAM,aAAa;IACxB,wBAAwB;;;CAGhB,CAAC;AAGX,eAAO,MAAM,QAAQ;IACnB,wBAAwB;;;CAGhB,CAAC"}