@form-engine-ts/storage 5.0.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 ADDED
@@ -0,0 +1 @@
1
+ MIT License
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # @form-engine-ts/storage
2
+
3
+ Shared storage cursor contracts and filter-aware pagination helpers for Form Engine storage adapters.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @form-engine-ts/storage
9
+ ```
10
+
11
+ The package exports `StorageCursor`, cursor payload contracts, cursor encoders/decoders, and
12
+ `paginateWithFilter` for adapters that need to scan native pages until enough filtered items are collected.
13
+ `maxScanPages` bounds low-density scans, and `totalScannedCount` reports the amount of source data inspected.
File without changes
@@ -0,0 +1,50 @@
1
+ // src/pagination.ts
2
+ import {
3
+ decodeStorageSubmissionCursor,
4
+ decodeStorageTextAnswerCursor,
5
+ encodeStorageSubmissionCursor,
6
+ encodeStorageTextAnswerCursor
7
+ } from "@form-engine-ts/core";
8
+ async function paginateWithFilter(params) {
9
+ const { pageSize, cursor, maxScanPages = 5, fetchPage, filterPredicate, encodeCursor } = params;
10
+ if (!Number.isSafeInteger(pageSize) || pageSize < 1) {
11
+ throw new TypeError("pageSize must be a positive safe integer.");
12
+ }
13
+ if (!Number.isSafeInteger(maxScanPages) || maxScanPages < 1) {
14
+ throw new TypeError("maxScanPages must be a positive safe integer.");
15
+ }
16
+ const collected = [];
17
+ let currentRawCursor = cursor;
18
+ let totalScannedCount = 0;
19
+ let scanCount = 0;
20
+ while (collected.length < pageSize && scanCount < maxScanPages) {
21
+ scanCount += 1;
22
+ const { rawItems, rawNextCursor } = await fetchPage(currentRawCursor, pageSize - collected.length + 1);
23
+ totalScannedCount += rawItems.length;
24
+ for (const item of rawItems) {
25
+ if (!filterPredicate(item)) continue;
26
+ collected.push(item);
27
+ if (collected.length === pageSize) {
28
+ const lastItem = collected.at(-1);
29
+ if (lastItem === void 0) break;
30
+ return {
31
+ items: collected,
32
+ hasMore: rawNextCursor !== void 0,
33
+ ...rawNextCursor === void 0 ? {} : { nextCursor: encodeCursor(lastItem) },
34
+ totalScannedCount
35
+ };
36
+ }
37
+ }
38
+ if (rawItems.length === 0 || rawNextCursor === void 0) break;
39
+ currentRawCursor = rawNextCursor;
40
+ }
41
+ return { items: collected, hasMore: false, totalScannedCount };
42
+ }
43
+
44
+ export {
45
+ paginateWithFilter,
46
+ decodeStorageSubmissionCursor,
47
+ decodeStorageTextAnswerCursor,
48
+ encodeStorageSubmissionCursor,
49
+ encodeStorageTextAnswerCursor
50
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ decodeStorageSubmissionCursor: () => import_core.decodeStorageSubmissionCursor,
24
+ decodeStorageTextAnswerCursor: () => import_core.decodeStorageTextAnswerCursor,
25
+ encodeStorageSubmissionCursor: () => import_core.encodeStorageSubmissionCursor,
26
+ encodeStorageTextAnswerCursor: () => import_core.encodeStorageTextAnswerCursor,
27
+ paginateWithFilter: () => paginateWithFilter
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/pagination.ts
32
+ var import_core = require("@form-engine-ts/core");
33
+ async function paginateWithFilter(params) {
34
+ const { pageSize, cursor, maxScanPages = 5, fetchPage, filterPredicate, encodeCursor } = params;
35
+ if (!Number.isSafeInteger(pageSize) || pageSize < 1) {
36
+ throw new TypeError("pageSize must be a positive safe integer.");
37
+ }
38
+ if (!Number.isSafeInteger(maxScanPages) || maxScanPages < 1) {
39
+ throw new TypeError("maxScanPages must be a positive safe integer.");
40
+ }
41
+ const collected = [];
42
+ let currentRawCursor = cursor;
43
+ let totalScannedCount = 0;
44
+ let scanCount = 0;
45
+ while (collected.length < pageSize && scanCount < maxScanPages) {
46
+ scanCount += 1;
47
+ const { rawItems, rawNextCursor } = await fetchPage(currentRawCursor, pageSize - collected.length + 1);
48
+ totalScannedCount += rawItems.length;
49
+ for (const item of rawItems) {
50
+ if (!filterPredicate(item)) continue;
51
+ collected.push(item);
52
+ if (collected.length === pageSize) {
53
+ const lastItem = collected.at(-1);
54
+ if (lastItem === void 0) break;
55
+ return {
56
+ items: collected,
57
+ hasMore: rawNextCursor !== void 0,
58
+ ...rawNextCursor === void 0 ? {} : { nextCursor: encodeCursor(lastItem) },
59
+ totalScannedCount
60
+ };
61
+ }
62
+ }
63
+ if (rawItems.length === 0 || rawNextCursor === void 0) break;
64
+ currentRawCursor = rawNextCursor;
65
+ }
66
+ return { items: collected, hasMore: false, totalScannedCount };
67
+ }
68
+ // Annotate the CommonJS export names for ESM import in node:
69
+ 0 && (module.exports = {
70
+ decodeStorageSubmissionCursor,
71
+ decodeStorageTextAnswerCursor,
72
+ encodeStorageSubmissionCursor,
73
+ encodeStorageTextAnswerCursor,
74
+ paginateWithFilter
75
+ });
@@ -0,0 +1,2 @@
1
+ export { paginateWithFilter } from './pagination.cjs';
2
+ export { CursorPagingOptions, PaginatedResult, StorageCursor, StorageFilterCriteria, SubmissionCursorPayload, TextAnswerCursorPayload, decodeStorageSubmissionCursor, decodeStorageTextAnswerCursor, encodeStorageSubmissionCursor, encodeStorageTextAnswerCursor } from '@form-engine-ts/core';
@@ -0,0 +1,2 @@
1
+ export { paginateWithFilter } from './pagination.js';
2
+ export { CursorPagingOptions, PaginatedResult, StorageCursor, StorageFilterCriteria, SubmissionCursorPayload, TextAnswerCursorPayload, decodeStorageSubmissionCursor, decodeStorageTextAnswerCursor, encodeStorageSubmissionCursor, encodeStorageTextAnswerCursor } from '@form-engine-ts/core';
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ import {
2
+ decodeStorageSubmissionCursor,
3
+ decodeStorageTextAnswerCursor,
4
+ encodeStorageSubmissionCursor,
5
+ encodeStorageTextAnswerCursor,
6
+ paginateWithFilter
7
+ } from "./chunk-RT2I36BE.js";
8
+ import "./chunk-6F4PWJZI.js";
9
+ export {
10
+ decodeStorageSubmissionCursor,
11
+ decodeStorageTextAnswerCursor,
12
+ encodeStorageSubmissionCursor,
13
+ encodeStorageTextAnswerCursor,
14
+ paginateWithFilter
15
+ };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/pagination.ts
21
+ var pagination_exports = {};
22
+ __export(pagination_exports, {
23
+ decodeStorageSubmissionCursor: () => import_core.decodeStorageSubmissionCursor,
24
+ decodeStorageTextAnswerCursor: () => import_core.decodeStorageTextAnswerCursor,
25
+ encodeStorageSubmissionCursor: () => import_core.encodeStorageSubmissionCursor,
26
+ encodeStorageTextAnswerCursor: () => import_core.encodeStorageTextAnswerCursor,
27
+ paginateWithFilter: () => paginateWithFilter
28
+ });
29
+ module.exports = __toCommonJS(pagination_exports);
30
+ var import_core = require("@form-engine-ts/core");
31
+ async function paginateWithFilter(params) {
32
+ const { pageSize, cursor, maxScanPages = 5, fetchPage, filterPredicate, encodeCursor } = params;
33
+ if (!Number.isSafeInteger(pageSize) || pageSize < 1) {
34
+ throw new TypeError("pageSize must be a positive safe integer.");
35
+ }
36
+ if (!Number.isSafeInteger(maxScanPages) || maxScanPages < 1) {
37
+ throw new TypeError("maxScanPages must be a positive safe integer.");
38
+ }
39
+ const collected = [];
40
+ let currentRawCursor = cursor;
41
+ let totalScannedCount = 0;
42
+ let scanCount = 0;
43
+ while (collected.length < pageSize && scanCount < maxScanPages) {
44
+ scanCount += 1;
45
+ const { rawItems, rawNextCursor } = await fetchPage(currentRawCursor, pageSize - collected.length + 1);
46
+ totalScannedCount += rawItems.length;
47
+ for (const item of rawItems) {
48
+ if (!filterPredicate(item)) continue;
49
+ collected.push(item);
50
+ if (collected.length === pageSize) {
51
+ const lastItem = collected.at(-1);
52
+ if (lastItem === void 0) break;
53
+ return {
54
+ items: collected,
55
+ hasMore: rawNextCursor !== void 0,
56
+ ...rawNextCursor === void 0 ? {} : { nextCursor: encodeCursor(lastItem) },
57
+ totalScannedCount
58
+ };
59
+ }
60
+ }
61
+ if (rawItems.length === 0 || rawNextCursor === void 0) break;
62
+ currentRawCursor = rawNextCursor;
63
+ }
64
+ return { items: collected, hasMore: false, totalScannedCount };
65
+ }
66
+ // Annotate the CommonJS export names for ESM import in node:
67
+ 0 && (module.exports = {
68
+ decodeStorageSubmissionCursor,
69
+ decodeStorageTextAnswerCursor,
70
+ encodeStorageSubmissionCursor,
71
+ encodeStorageTextAnswerCursor,
72
+ paginateWithFilter
73
+ });
@@ -0,0 +1,16 @@
1
+ import { StorageCursor, PaginatedResult } from '@form-engine-ts/core';
2
+ export { CursorPagingOptions, PaginatedResult, StorageCursor, decodeStorageSubmissionCursor, decodeStorageTextAnswerCursor, encodeStorageSubmissionCursor, encodeStorageTextAnswerCursor } from '@form-engine-ts/core';
3
+
4
+ declare function paginateWithFilter<T>(params: {
5
+ readonly pageSize: number;
6
+ readonly cursor?: StorageCursor;
7
+ readonly maxScanPages?: number;
8
+ readonly fetchPage: (rawCursor: StorageCursor | undefined, limit: number) => Promise<{
9
+ readonly rawItems: readonly T[];
10
+ readonly rawNextCursor?: StorageCursor;
11
+ }>;
12
+ readonly filterPredicate: (item: T) => boolean;
13
+ readonly encodeCursor: (lastItem: T) => StorageCursor;
14
+ }): Promise<PaginatedResult<T>>;
15
+
16
+ export { paginateWithFilter };
@@ -0,0 +1,16 @@
1
+ import { StorageCursor, PaginatedResult } from '@form-engine-ts/core';
2
+ export { CursorPagingOptions, PaginatedResult, StorageCursor, decodeStorageSubmissionCursor, decodeStorageTextAnswerCursor, encodeStorageSubmissionCursor, encodeStorageTextAnswerCursor } from '@form-engine-ts/core';
3
+
4
+ declare function paginateWithFilter<T>(params: {
5
+ readonly pageSize: number;
6
+ readonly cursor?: StorageCursor;
7
+ readonly maxScanPages?: number;
8
+ readonly fetchPage: (rawCursor: StorageCursor | undefined, limit: number) => Promise<{
9
+ readonly rawItems: readonly T[];
10
+ readonly rawNextCursor?: StorageCursor;
11
+ }>;
12
+ readonly filterPredicate: (item: T) => boolean;
13
+ readonly encodeCursor: (lastItem: T) => StorageCursor;
14
+ }): Promise<PaginatedResult<T>>;
15
+
16
+ export { paginateWithFilter };
@@ -0,0 +1,14 @@
1
+ import {
2
+ decodeStorageSubmissionCursor,
3
+ decodeStorageTextAnswerCursor,
4
+ encodeStorageSubmissionCursor,
5
+ encodeStorageTextAnswerCursor,
6
+ paginateWithFilter
7
+ } from "./chunk-RT2I36BE.js";
8
+ export {
9
+ decodeStorageSubmissionCursor,
10
+ decodeStorageTextAnswerCursor,
11
+ encodeStorageSubmissionCursor,
12
+ encodeStorageTextAnswerCursor,
13
+ paginateWithFilter
14
+ };
package/dist/types.cjs ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1 @@
1
+ export { CursorPagingOptions, PaginatedResult, StorageCursor, StorageFilterCriteria, SubmissionCursorPayload, TextAnswerCursorPayload } from '@form-engine-ts/core';
@@ -0,0 +1 @@
1
+ export { CursorPagingOptions, PaginatedResult, StorageCursor, StorageFilterCriteria, SubmissionCursorPayload, TextAnswerCursorPayload } from '@form-engine-ts/core';
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ import "./chunk-6F4PWJZI.js";
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@form-engine-ts/storage",
3
+ "version": "5.0.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "main": "./dist/index.cjs",
15
+ "module": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "require": "./dist/index.cjs"
22
+ },
23
+ "./types": {
24
+ "types": "./dist/types.d.ts",
25
+ "import": "./dist/types.js",
26
+ "require": "./dist/types.cjs"
27
+ },
28
+ "./pagination": {
29
+ "types": "./dist/pagination.d.ts",
30
+ "import": "./dist/pagination.js",
31
+ "require": "./dist/pagination.cjs"
32
+ }
33
+ },
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/nitta-a/form-engine-ts.git"
38
+ },
39
+ "dependencies": {
40
+ "@form-engine-ts/core": "5.0.1"
41
+ },
42
+ "scripts": {
43
+ "build": "tsup src/index.ts src/types.ts src/pagination.ts --format esm,cjs --dts --clean --external @form-engine-ts/core",
44
+ "check": "biome check . && tsc --noEmit",
45
+ "test": "vitest run --globals",
46
+ "typecheck": "tsc --noEmit"
47
+ }
48
+ }