@form-engine-ts/storage-localstorage 8.0.0 → 8.0.2
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/dist/index.cjs +24 -0
- package/dist/index.js +26 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -123,6 +123,30 @@ function createLocalStorageAdapter(storagePrefix = "pf_", injectedStorage, optio
|
|
|
123
123
|
if (storage.getItem(key) !== null) throw new Error(`A submission with ID "${submission.id}" already exists.`);
|
|
124
124
|
storage.setItem(key, JSON.stringify(submission));
|
|
125
125
|
},
|
|
126
|
+
async saveSubmissionWithinLimit(submission, maxResponses, saveOptions = {}) {
|
|
127
|
+
if (!Number.isInteger(maxResponses) || maxResponses < 1)
|
|
128
|
+
throw new RangeError("maxResponses must be a positive integer.");
|
|
129
|
+
const key = submissionKey(submission.id);
|
|
130
|
+
const payloadHash = await (0, import_core.hashFormSubmissionPayload)(submission);
|
|
131
|
+
const existingValue = storage.getItem(key);
|
|
132
|
+
if (existingValue !== null) {
|
|
133
|
+
if (saveOptions.idempotent !== true) throw new Error(`A submission with ID "${submission.id}" already exists.`);
|
|
134
|
+
const existing = parseSubmission(existingValue, key);
|
|
135
|
+
const existingPayloadHash = await (0, import_core.hashFormSubmissionPayload)(existing);
|
|
136
|
+
if (existingPayloadHash === payloadHash)
|
|
137
|
+
return { status: "duplicate", submission: cloneJson(existing), payloadHash };
|
|
138
|
+
return { status: "conflict", submissionId: submission.id, payloadHash, existingPayloadHash };
|
|
139
|
+
}
|
|
140
|
+
const count = prefixedKeys(submissionPrefix).reduce((total, key2) => {
|
|
141
|
+
const value = storage.getItem(key2);
|
|
142
|
+
if (value === null) return total;
|
|
143
|
+
const candidate = parseSubmission(value, key2);
|
|
144
|
+
return total + (candidate.formId === submission.formId && candidate.formVersion === submission.formVersion ? 1 : 0);
|
|
145
|
+
}, 0);
|
|
146
|
+
if (count >= maxResponses) return { status: "limit_reached" };
|
|
147
|
+
storage.setItem(key, JSON.stringify(submission));
|
|
148
|
+
if (saveOptions.idempotent === true) return { status: "created", submission: cloneJson(submission), payloadHash };
|
|
149
|
+
},
|
|
126
150
|
async listSubmissions(formId, formVersion, options2) {
|
|
127
151
|
return prefixedKeys(submissionPrefix).map((key) => {
|
|
128
152
|
const value = storage.getItem(key);
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import {
|
|
3
3
|
assertValidFormSchema,
|
|
4
|
-
createFormLifecycleAdapter
|
|
4
|
+
createFormLifecycleAdapter,
|
|
5
|
+
hashFormSubmissionPayload
|
|
5
6
|
} from "@form-engine-ts/core";
|
|
6
7
|
function isRecord(value) {
|
|
7
8
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -102,6 +103,30 @@ function createLocalStorageAdapter(storagePrefix = "pf_", injectedStorage, optio
|
|
|
102
103
|
if (storage.getItem(key) !== null) throw new Error(`A submission with ID "${submission.id}" already exists.`);
|
|
103
104
|
storage.setItem(key, JSON.stringify(submission));
|
|
104
105
|
},
|
|
106
|
+
async saveSubmissionWithinLimit(submission, maxResponses, saveOptions = {}) {
|
|
107
|
+
if (!Number.isInteger(maxResponses) || maxResponses < 1)
|
|
108
|
+
throw new RangeError("maxResponses must be a positive integer.");
|
|
109
|
+
const key = submissionKey(submission.id);
|
|
110
|
+
const payloadHash = await hashFormSubmissionPayload(submission);
|
|
111
|
+
const existingValue = storage.getItem(key);
|
|
112
|
+
if (existingValue !== null) {
|
|
113
|
+
if (saveOptions.idempotent !== true) throw new Error(`A submission with ID "${submission.id}" already exists.`);
|
|
114
|
+
const existing = parseSubmission(existingValue, key);
|
|
115
|
+
const existingPayloadHash = await hashFormSubmissionPayload(existing);
|
|
116
|
+
if (existingPayloadHash === payloadHash)
|
|
117
|
+
return { status: "duplicate", submission: cloneJson(existing), payloadHash };
|
|
118
|
+
return { status: "conflict", submissionId: submission.id, payloadHash, existingPayloadHash };
|
|
119
|
+
}
|
|
120
|
+
const count = prefixedKeys(submissionPrefix).reduce((total, key2) => {
|
|
121
|
+
const value = storage.getItem(key2);
|
|
122
|
+
if (value === null) return total;
|
|
123
|
+
const candidate = parseSubmission(value, key2);
|
|
124
|
+
return total + (candidate.formId === submission.formId && candidate.formVersion === submission.formVersion ? 1 : 0);
|
|
125
|
+
}, 0);
|
|
126
|
+
if (count >= maxResponses) return { status: "limit_reached" };
|
|
127
|
+
storage.setItem(key, JSON.stringify(submission));
|
|
128
|
+
if (saveOptions.idempotent === true) return { status: "created", submission: cloneJson(submission), payloadHash };
|
|
129
|
+
},
|
|
105
130
|
async listSubmissions(formId, formVersion, options2) {
|
|
106
131
|
return prefixedKeys(submissionPrefix).map((key) => {
|
|
107
132
|
const value = storage.getItem(key);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@form-engine-ts/storage-localstorage",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"typescript"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@form-engine-ts/core": "8.0.
|
|
42
|
+
"@form-engine-ts/core": "8.0.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@form-engine-ts/storage": "8.0.
|
|
45
|
+
"@form-engine-ts/storage": "8.0.2"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsup src/index.ts --format esm,cjs --dts --clean --external @form-engine-ts/core",
|