summaryrefslogtreecommitdiff
path: root/packages/idb-bridge/src/util/makeStoreKeyValue.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/idb-bridge/src/util/makeStoreKeyValue.ts')
-rw-r--r--packages/idb-bridge/src/util/makeStoreKeyValue.ts92
1 files changed, 92 insertions, 0 deletions
diff --git a/packages/idb-bridge/src/util/makeStoreKeyValue.ts b/packages/idb-bridge/src/util/makeStoreKeyValue.ts
new file mode 100644
index 000000000..4850cec26
--- /dev/null
+++ b/packages/idb-bridge/src/util/makeStoreKeyValue.ts
@@ -0,0 +1,92 @@
+import { Value, Key, KeyPath } from "./types";
+import extractKey from "./extractKey";
+import { DataError } from "./errors";
+import valueToKey from "./valueToKey";
+import structuredClone from "./structuredClone";
+import injectKey from "./injectKey";
+
+export interface StoreKeyResult {
+ updatedKeyGenerator: number;
+ key: Key;
+ value: Value;
+}
+
+export function makeStoreKeyValue(
+ value: Value,
+ key: Key | undefined,
+ currentKeyGenerator: number,
+ autoIncrement: boolean,
+ keyPath: KeyPath | null,
+): StoreKeyResult {
+ const haveKey = key !== undefined && key !== null;
+ const haveKeyPath = keyPath !== null && keyPath !== undefined;
+
+ // This models a decision table on (haveKey, haveKeyPath, autoIncrement)
+
+ value = structuredClone(value);
+
+ if (haveKey) {
+ if (haveKeyPath) {
+ // (yes, yes, no)
+ // (yes, yes, yes)
+ throw new DataError();
+ } else {
+ if (autoIncrement) {
+ // (yes, no, yes)
+ key = valueToKey(key)!;
+ let updatedKeyGenerator: number;
+ if (typeof key !== "number") {
+ updatedKeyGenerator = currentKeyGenerator;
+ } else {
+ updatedKeyGenerator = key;
+ }
+ return {
+ key: key!,
+ value: value,
+ updatedKeyGenerator,
+ };
+ } else {
+ // (yes, no, no)
+ throw new DataError();
+ }
+ }
+ } else {
+ if (haveKeyPath) {
+ if (autoIncrement) {
+ // (no, yes, yes)
+
+ let updatedKeyGenerator: number;
+ const maybeInlineKey = extractKey(keyPath!, value);
+ if (maybeInlineKey === undefined) {
+ value = injectKey(keyPath!, value, currentKeyGenerator);
+ key = currentKeyGenerator;
+ updatedKeyGenerator = currentKeyGenerator + 1;
+ } else if (typeof maybeInlineKey === "number") {
+ key = maybeInlineKey;
+ updatedKeyGenerator = maybeInlineKey;
+ } else {
+ key = maybeInlineKey;
+ updatedKeyGenerator = currentKeyGenerator + 1;
+ }
+ return {
+ key: key,
+ value: value,
+ updatedKeyGenerator,
+ }
+ } else {
+ // (no, yes, no)
+ key = extractKey(keyPath!, value);
+ key = valueToKey(key);
+ return {
+ key: key!,
+ value: value,
+ updatedKeyGenerator: currentKeyGenerator,
+ };
+ }
+ } else {
+ // (no, no, yes)
+ // (no, no, no)
+ throw new DataError();
+ }
+ }
+} \ No newline at end of file