@jfdevelops/multi-step-form-core 1.0.0-alpha.17 → 1.0.0-alpha.18
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/_internals.cjs +14 -0
- package/dist/_internals.d.cts +4 -0
- package/dist/_internals.d.mts +4 -0
- package/dist/_internals.mjs +5 -0
- package/dist/index.cjs +49 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.mjs +16 -0
- package/dist/internals/step-schema.cjs +389 -0
- package/dist/internals/step-schema.cjs.map +1 -0
- package/dist/internals/step-schema.d.cts +41 -0
- package/dist/internals/step-schema.d.cts.map +1 -0
- package/dist/internals/step-schema.d.mts +41 -0
- package/dist/internals/step-schema.d.mts.map +1 -0
- package/dist/internals/step-schema.mjs +389 -0
- package/dist/internals/step-schema.mjs.map +1 -0
- package/dist/internals/utils.cjs +94 -0
- package/dist/internals/utils.cjs.map +1 -0
- package/dist/internals/utils.d.cts +27 -0
- package/dist/internals/utils.d.cts.map +1 -0
- package/dist/internals/utils.d.mts +27 -0
- package/dist/internals/utils.d.mts.map +1 -0
- package/dist/internals/utils.mjs +91 -0
- package/dist/internals/utils.mjs.map +1 -0
- package/dist/observable.cjs +44 -0
- package/dist/observable.cjs.map +1 -0
- package/dist/observable.d.cts +26 -0
- package/dist/observable.d.cts.map +1 -0
- package/dist/observable.d.mts +26 -0
- package/dist/observable.d.mts.map +1 -0
- package/dist/observable.mjs +44 -0
- package/dist/observable.mjs.map +1 -0
- package/dist/schema.cjs +68 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +28 -0
- package/dist/schema.d.cts.map +1 -0
- package/dist/schema.d.mts +28 -0
- package/dist/schema.d.mts.map +1 -0
- package/dist/schema.mjs +67 -0
- package/dist/schema.mjs.map +1 -0
- package/dist/steps/fields.cjs +23 -0
- package/dist/steps/fields.cjs.map +1 -0
- package/dist/steps/fields.d.cts +18 -0
- package/dist/steps/fields.d.cts.map +1 -0
- package/dist/steps/fields.d.mts +18 -0
- package/dist/steps/fields.d.mts.map +1 -0
- package/dist/steps/fields.mjs +18 -0
- package/dist/steps/fields.mjs.map +1 -0
- package/dist/steps/index.cjs +4 -0
- package/dist/steps/index.mjs +6 -0
- package/dist/steps/schema.cjs +194 -0
- package/dist/steps/schema.cjs.map +1 -0
- package/dist/steps/schema.d.cts +124 -0
- package/dist/steps/schema.d.cts.map +1 -0
- package/dist/steps/schema.d.mts +124 -0
- package/dist/steps/schema.d.mts.map +1 -0
- package/dist/steps/schema.mjs +194 -0
- package/dist/steps/schema.mjs.map +1 -0
- package/dist/steps/types.cjs +33 -0
- package/dist/steps/types.cjs.map +1 -0
- package/dist/steps/types.d.cts +332 -0
- package/dist/steps/types.d.cts.map +1 -0
- package/dist/steps/types.d.mts +332 -0
- package/dist/steps/types.d.mts.map +1 -0
- package/dist/steps/types.mjs +27 -0
- package/dist/steps/types.mjs.map +1 -0
- package/dist/steps/utils.cjs +96 -0
- package/dist/steps/utils.cjs.map +1 -0
- package/dist/steps/utils.d.cts +10 -0
- package/dist/steps/utils.d.cts.map +1 -0
- package/dist/steps/utils.d.mts +10 -0
- package/dist/steps/utils.d.mts.map +1 -0
- package/dist/steps/utils.mjs +94 -0
- package/dist/steps/utils.mjs.map +1 -0
- package/dist/storage.cjs +68 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +33 -0
- package/dist/storage.d.cts.map +1 -0
- package/dist/storage.d.mts +33 -0
- package/dist/storage.d.mts.map +1 -0
- package/dist/storage.mjs +67 -0
- package/dist/storage.mjs.map +1 -0
- package/dist/subscribable.cjs +25 -0
- package/dist/subscribable.cjs.map +1 -0
- package/dist/subscribable.d.cts +14 -0
- package/dist/subscribable.d.cts.map +1 -0
- package/dist/subscribable.d.mts +14 -0
- package/dist/subscribable.d.mts.map +1 -0
- package/dist/subscribable.mjs +24 -0
- package/dist/subscribable.mjs.map +1 -0
- package/dist/utils/casing.cjs +63 -0
- package/dist/utils/casing.cjs.map +1 -0
- package/dist/utils/casing.d.cts +40 -0
- package/dist/utils/casing.d.cts.map +1 -0
- package/dist/utils/casing.d.mts +40 -0
- package/dist/utils/casing.d.mts.map +1 -0
- package/dist/utils/casing.mjs +57 -0
- package/dist/utils/casing.mjs.map +1 -0
- package/dist/utils/field-types.cjs +23 -0
- package/dist/utils/field-types.cjs.map +1 -0
- package/dist/utils/field-types.d.cts +11 -0
- package/dist/utils/field-types.d.cts.map +1 -0
- package/dist/utils/field-types.d.mts +11 -0
- package/dist/utils/field-types.d.mts.map +1 -0
- package/dist/utils/field-types.mjs +20 -0
- package/dist/utils/field-types.mjs.map +1 -0
- package/dist/utils/helpers.cjs +30 -0
- package/dist/utils/helpers.cjs.map +1 -0
- package/dist/utils/helpers.mjs +27 -0
- package/dist/utils/helpers.mjs.map +1 -0
- package/dist/utils/invariant.cjs +18 -0
- package/dist/utils/invariant.cjs.map +1 -0
- package/dist/utils/invariant.d.cts +5 -0
- package/dist/utils/invariant.d.cts.map +1 -0
- package/dist/utils/invariant.d.mts +5 -0
- package/dist/utils/invariant.d.mts.map +1 -0
- package/dist/utils/invariant.mjs +17 -0
- package/dist/utils/invariant.mjs.map +1 -0
- package/dist/utils/logger.cjs +58 -0
- package/dist/utils/logger.cjs.map +1 -0
- package/dist/utils/logger.d.cts +53 -0
- package/dist/utils/logger.d.cts.map +1 -0
- package/dist/utils/logger.d.mts +53 -0
- package/dist/utils/logger.d.mts.map +1 -0
- package/dist/utils/logger.mjs +56 -0
- package/dist/utils/logger.mjs.map +1 -0
- package/dist/utils/path.cjs +331 -0
- package/dist/utils/path.cjs.map +1 -0
- package/dist/utils/path.d.cts +139 -0
- package/dist/utils/path.d.cts.map +1 -0
- package/dist/utils/path.d.mts +139 -0
- package/dist/utils/path.d.mts.map +1 -0
- package/dist/utils/path.mjs +325 -0
- package/dist/utils/path.mjs.map +1 -0
- package/dist/utils/types.d.cts +25 -0
- package/dist/utils/types.d.cts.map +1 -0
- package/dist/utils/types.d.mts +25 -0
- package/dist/utils/types.d.mts.map +1 -0
- package/dist/utils/validator.cjs +12 -0
- package/dist/utils/validator.cjs.map +1 -0
- package/dist/utils/validator.d.cts +77 -0
- package/dist/utils/validator.d.cts.map +1 -0
- package/dist/utils/validator.d.mts +77 -0
- package/dist/utils/validator.d.mts.map +1 -0
- package/dist/utils/validator.mjs +11 -0
- package/dist/utils/validator.mjs.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const require_helpers = require('../utils/helpers.cjs');
|
|
2
|
+
const require_invariant = require('../utils/invariant.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/steps/utils.ts
|
|
5
|
+
/**
|
|
6
|
+
* Gets the step number from an input string.
|
|
7
|
+
* @param input The input to extract the step number from.
|
|
8
|
+
* @returns The extracted step number.
|
|
9
|
+
*/
|
|
10
|
+
function extractNumber(input) {
|
|
11
|
+
require_invariant.invariant(input.includes("step"), "Can't extract a valid step number since");
|
|
12
|
+
const extracted = input.replace("step", "");
|
|
13
|
+
require_invariant.invariant(/^\d+$/.test(extracted), `Invalid step format: "${input}"`);
|
|
14
|
+
return Number.parseInt(extracted, 10);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A factory function to get the data of a specific step.
|
|
18
|
+
* @param resolvedStepValues The resolved step values.
|
|
19
|
+
* @returns A function to get specific step data from a target step.
|
|
20
|
+
*/
|
|
21
|
+
function getStep(resolvedStepValues) {
|
|
22
|
+
/**
|
|
23
|
+
* Gets the step data associated with the target step number.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const result = getStep(resolvedStepValues)({ step: 1 });
|
|
27
|
+
* // result: { step: 1, data: ... }
|
|
28
|
+
*
|
|
29
|
+
* @returns An object containing the `step` number and the associated step data.
|
|
30
|
+
*/
|
|
31
|
+
return function(options) {
|
|
32
|
+
const { step } = options;
|
|
33
|
+
return {
|
|
34
|
+
step,
|
|
35
|
+
data: resolvedStepValues[`step${step}`]
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function createCtxHelper(values, data) {
|
|
40
|
+
return data.reduce((acc, curr) => {
|
|
41
|
+
const stepNumber = extractNumber(curr);
|
|
42
|
+
const { data: data$1 } = getStep(values)({ step: stepNumber });
|
|
43
|
+
for (const [key, value] of Object.entries(data$1)) {
|
|
44
|
+
if (typeof value === "function" && key !== "update") continue;
|
|
45
|
+
data$1[key] = value;
|
|
46
|
+
}
|
|
47
|
+
acc[curr] = data$1;
|
|
48
|
+
return acc;
|
|
49
|
+
}, {});
|
|
50
|
+
}
|
|
51
|
+
function createCtx(values, stepData) {
|
|
52
|
+
const formatter = new Intl.ListFormat("en", {
|
|
53
|
+
style: "long",
|
|
54
|
+
type: "disjunction"
|
|
55
|
+
});
|
|
56
|
+
const validStepKeys = Object.keys(values);
|
|
57
|
+
const baseErrorMessage = () => {
|
|
58
|
+
return `"stepData" must be set to an array of available steps (${formatter.format(validStepKeys)})`;
|
|
59
|
+
};
|
|
60
|
+
if (stepData === "all") {
|
|
61
|
+
let ctx = {};
|
|
62
|
+
for (const key of validStepKeys) ctx = {
|
|
63
|
+
...ctx,
|
|
64
|
+
[key]: getStep(values)({ step: extractNumber(key) })
|
|
65
|
+
};
|
|
66
|
+
return createCtxHelper(values, validStepKeys);
|
|
67
|
+
}
|
|
68
|
+
if (Array.isArray(stepData)) {
|
|
69
|
+
require_invariant.invariant(stepData.every((step) => validStepKeys.includes(step)), () => {
|
|
70
|
+
const comparedResults = require_helpers.comparePartialArray(stepData, validStepKeys.map((key) => extractNumber(key)), formatter);
|
|
71
|
+
if (comparedResults.status === "error") return `${baseErrorMessage()}. See errors:\n ${require_helpers.printErrors(comparedResults.errors)}`;
|
|
72
|
+
return baseErrorMessage();
|
|
73
|
+
});
|
|
74
|
+
return createCtxHelper(values, stepData);
|
|
75
|
+
}
|
|
76
|
+
if (typeof stepData === "object") {
|
|
77
|
+
const keys = Object.keys(stepData);
|
|
78
|
+
require_invariant.invariant(keys.every((key) => validStepKeys.includes(key)), () => {
|
|
79
|
+
const comparedResults = require_helpers.comparePartialArray(keys, validStepKeys, formatter);
|
|
80
|
+
if (comparedResults.status === "error") return `${baseErrorMessage()}. See errors:\n ${require_helpers.printErrors(comparedResults.errors)}`;
|
|
81
|
+
return baseErrorMessage();
|
|
82
|
+
});
|
|
83
|
+
return createCtxHelper(values, keys);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`${baseErrorMessage()} OR to "all"`);
|
|
86
|
+
}
|
|
87
|
+
function functionalUpdate(updater, input) {
|
|
88
|
+
if (typeof updater === "function") return updater(input);
|
|
89
|
+
return updater;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
exports.createCtx = createCtx;
|
|
94
|
+
exports.functionalUpdate = functionalUpdate;
|
|
95
|
+
exports.getStep = getStep;
|
|
96
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["data","comparePartialArray","printErrors"],"sources":["../../src/steps/utils.ts"],"sourcesContent":["import { comparePartialArray, printErrors } from '@/utils/helpers';\nimport { invariant } from '@/utils/invariant';\nimport type {\n AnyResolvedStep,\n GetCurrentStep,\n HelperFnChosenSteps,\n HelperFnCtx,\n StepNumbers,\n Updater,\n} from './types';\n\nexport type GetStepOptions<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TStepNumber extends TStepNumbers\n> = { step: TStepNumber };\n\n/**\n * Gets the step number from an input string.\n * @param input The input to extract the step number from.\n * @returns The extracted step number.\n */\nexport function extractNumber(input: string) {\n invariant(input.includes('step'), \"Can't extract a valid step number since\");\n\n const extracted = input.replace('step', '');\n\n invariant(/^\\d+$/.test(extracted), `Invalid step format: \"${input}\"`);\n\n return Number.parseInt(extracted, 10);\n}\n\n/**\n * A factory function to get the data of a specific step.\n * @param resolvedStepValues The resolved step values.\n * @returns A function to get specific step data from a target step.\n */\nexport function getStep<\n resolvedStep extends AnyResolvedStep,\n stepNumbers extends StepNumbers<resolvedStep>\n>(resolvedStepValues: resolvedStep) {\n /**\n * Gets the step data associated with the target step number.\n *\n * @example\n * const result = getStep(resolvedStepValues)({ step: 1 });\n * // result: { step: 1, data: ... }\n *\n * @returns An object containing the `step` number and the associated step data.\n */\n return function <stepNumber extends stepNumbers>(\n options: GetStepOptions<resolvedStep, stepNumbers, stepNumber>\n ) {\n const { step } = options;\n const stepKey = `step${step}` as keyof typeof resolvedStepValues;\n\n const data = resolvedStepValues[stepKey] as GetCurrentStep<\n typeof resolvedStepValues,\n stepNumber\n >;\n\n return { step, data };\n };\n}\n\nfunction createCtxHelper<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>\n>(values: TResolvedStep, data: string[]) {\n return data.reduce((acc, curr) => {\n const stepNumber = extractNumber(curr);\n const { data } = getStep(values)({\n step: stepNumber as TStepNumbers,\n });\n\n for (const [key, value] of Object.entries(data)) {\n // console.log({ [key]: value });\n // Remove the functions from the data to comply with `StrippedResolvedStep`\n if (typeof value === 'function' && key !== 'update') {\n continue;\n }\n\n data[key as keyof typeof data] = value as never;\n }\n\n acc[curr as keyof typeof acc] = data as never;\n\n return acc;\n }, {} as HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps>);\n}\n\nexport function createCtx<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>\n>(values: TResolvedStep, stepData: TChosenSteps) {\n const formatter = new Intl.ListFormat('en', {\n style: 'long',\n type: 'disjunction',\n });\n const validStepKeys = Object.keys(values);\n\n const baseErrorMessage = () => {\n return `\"stepData\" must be set to an array of available steps (${formatter.format(\n validStepKeys\n )})`;\n };\n\n if (stepData === 'all') {\n let ctx = {} as HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps>;\n\n for (const key of validStepKeys) {\n ctx = {\n ...ctx,\n [key]: getStep(values)({\n step: extractNumber(key) as never,\n }),\n };\n }\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n validStepKeys\n );\n }\n\n if (Array.isArray(stepData)) {\n invariant(\n stepData.every((step) => validStepKeys.includes(step)),\n () => {\n const comparedResults = comparePartialArray(\n stepData,\n validStepKeys.map((key) => extractNumber(key)),\n formatter\n );\n\n if (comparedResults.status === 'error') {\n return `${baseErrorMessage()}. See errors:\\n ${printErrors(\n comparedResults.errors\n )}`;\n }\n\n return baseErrorMessage();\n }\n );\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n stepData\n );\n }\n\n if (typeof stepData === 'object') {\n const keys = Object.keys(stepData);\n\n invariant(\n keys.every((key) => validStepKeys.includes(key)),\n () => {\n const comparedResults = comparePartialArray(\n keys,\n validStepKeys,\n formatter\n );\n\n if (comparedResults.status === 'error') {\n return `${baseErrorMessage()}. See errors:\\n ${printErrors(\n comparedResults.errors\n )}`;\n }\n\n return baseErrorMessage();\n }\n );\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n keys\n );\n }\n\n throw new Error(`${baseErrorMessage()} OR to \"all\"`);\n}\n\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput\n) {\n if (typeof updater === 'function') {\n return (updater as (_: TInput) => TOutput)(input);\n }\n\n return updater;\n}\n"],"mappings":";;;;;;;;;AAsBA,SAAgB,cAAc,OAAe;AAC3C,6BAAU,MAAM,SAAS,OAAO,EAAE,0CAA0C;CAE5E,MAAM,YAAY,MAAM,QAAQ,QAAQ,GAAG;AAE3C,6BAAU,QAAQ,KAAK,UAAU,EAAE,yBAAyB,MAAM,GAAG;AAErE,QAAO,OAAO,SAAS,WAAW,GAAG;;;;;;;AAQvC,SAAgB,QAGd,oBAAkC;;;;;;;;;;AAUlC,QAAO,SACL,SACA;EACA,MAAM,EAAE,SAAS;AAQjB,SAAO;GAAE;GAAM,MALF,mBAFG,OAAO;GAOF;;;AAIzB,SAAS,gBAIP,QAAuB,MAAgB;AACvC,QAAO,KAAK,QAAQ,KAAK,SAAS;EAChC,MAAM,aAAa,cAAc,KAAK;EACtC,MAAM,EAAE,iBAAS,QAAQ,OAAO,CAAC,EAC/B,MAAM,YACP,CAAC;AAEF,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQA,OAAK,EAAE;AAG/C,OAAI,OAAO,UAAU,cAAc,QAAQ,SACzC;AAGF,UAAK,OAA4B;;AAGnC,MAAI,QAA4BA;AAEhC,SAAO;IACN,EAAE,CAA2D;;AAGlE,SAAgB,UAId,QAAuB,UAAwB;CAC/C,MAAM,YAAY,IAAI,KAAK,WAAW,MAAM;EAC1C,OAAO;EACP,MAAM;EACP,CAAC;CACF,MAAM,gBAAgB,OAAO,KAAK,OAAO;CAEzC,MAAM,yBAAyB;AAC7B,SAAO,0DAA0D,UAAU,OACzE,cACD,CAAC;;AAGJ,KAAI,aAAa,OAAO;EACtB,IAAI,MAAM,EAAE;AAEZ,OAAK,MAAM,OAAO,cAChB,OAAM;GACJ,GAAG;IACF,MAAM,QAAQ,OAAO,CAAC,EACrB,MAAM,cAAc,IAAI,EACzB,CAAC;GACH;AAGH,SAAO,gBACL,QACA,cACD;;AAGH,KAAI,MAAM,QAAQ,SAAS,EAAE;AAC3B,8BACE,SAAS,OAAO,SAAS,cAAc,SAAS,KAAK,CAAC,QAChD;GACJ,MAAM,kBAAkBC,oCACtB,UACA,cAAc,KAAK,QAAQ,cAAc,IAAI,CAAC,EAC9C,UACD;AAED,OAAI,gBAAgB,WAAW,QAC7B,QAAO,GAAG,kBAAkB,CAAC,kBAAkBC,4BAC7C,gBAAgB,OACjB;AAGH,UAAO,kBAAkB;IAE5B;AAED,SAAO,gBACL,QACA,SACD;;AAGH,KAAI,OAAO,aAAa,UAAU;EAChC,MAAM,OAAO,OAAO,KAAK,SAAS;AAElC,8BACE,KAAK,OAAO,QAAQ,cAAc,SAAS,IAAI,CAAC,QAC1C;GACJ,MAAM,kBAAkBD,oCACtB,MACA,eACA,UACD;AAED,OAAI,gBAAgB,WAAW,QAC7B,QAAO,GAAG,kBAAkB,CAAC,kBAAkBC,4BAC7C,gBAAgB,OACjB;AAGH,UAAO,kBAAkB;IAE5B;AAED,SAAO,gBACL,QACA,KACD;;AAGH,OAAM,IAAI,MAAM,GAAG,kBAAkB,CAAC,cAAc;;AAGtD,SAAgB,iBACd,SACA,OACA;AACA,KAAI,OAAO,YAAY,WACrB,QAAQ,QAAmC,MAAM;AAGnD,QAAO"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AnyResolvedStep, HelperFnChosenSteps, HelperFnCtx, StepNumbers } from "./types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/steps/utils.d.ts
|
|
4
|
+
type GetStepOptions<TResolvedStep extends AnyResolvedStep, TStepNumbers extends StepNumbers<TResolvedStep>, TStepNumber extends TStepNumbers> = {
|
|
5
|
+
step: TStepNumber;
|
|
6
|
+
};
|
|
7
|
+
declare function createCtx<TResolvedStep extends AnyResolvedStep, TStepNumbers extends StepNumbers<TResolvedStep>, TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>>(values: TResolvedStep, stepData: TChosenSteps): HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps, never>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { GetStepOptions, createCtx };
|
|
10
|
+
//# sourceMappingURL=utils.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.cts","names":[],"sources":["../../src/steps/utils.ts"],"sourcesContent":[],"mappings":";;;KAWY,qCACY,sCACD,YAAY,oCACb;QACV;AAJZ,CAAA;AAqF+C,iBAJ/B,SAI+B,CAAA,sBAHvB,eAGuB,EAAA,qBAFxB,WAEwB,CAFZ,aAEY,CAAA,EAAA,qBADxB,mBACwB,CADJ,aACI,EADW,YACX,CAAA,CAAA,CAAA,MAAA,EAArC,aAAqC,EAAA,QAAA,EAAZ,YAAY,CAAA,EAAA,WAAA,CAAA,aAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AnyResolvedStep, HelperFnChosenSteps, HelperFnCtx, StepNumbers } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/steps/utils.d.ts
|
|
4
|
+
type GetStepOptions<TResolvedStep extends AnyResolvedStep, TStepNumbers extends StepNumbers<TResolvedStep>, TStepNumber extends TStepNumbers> = {
|
|
5
|
+
step: TStepNumber;
|
|
6
|
+
};
|
|
7
|
+
declare function createCtx<TResolvedStep extends AnyResolvedStep, TStepNumbers extends StepNumbers<TResolvedStep>, TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>>(values: TResolvedStep, stepData: TChosenSteps): HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps, never>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { GetStepOptions, createCtx };
|
|
10
|
+
//# sourceMappingURL=utils.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/steps/utils.ts"],"sourcesContent":[],"mappings":";;;KAWY,qCACY,sCACD,YAAY,oCACb;QACV;AAJZ,CAAA;AAqF+C,iBAJ/B,SAI+B,CAAA,sBAHvB,eAGuB,EAAA,qBAFxB,WAEwB,CAFZ,aAEY,CAAA,EAAA,qBADxB,mBACwB,CADJ,aACI,EADW,YACX,CAAA,CAAA,CAAA,MAAA,EAArC,aAAqC,EAAA,QAAA,EAAZ,YAAY,CAAA,EAAA,WAAA,CAAA,aAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,CAAA"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { comparePartialArray, printErrors } from "../utils/helpers.mjs";
|
|
2
|
+
import { invariant } from "../utils/invariant.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/steps/utils.ts
|
|
5
|
+
/**
|
|
6
|
+
* Gets the step number from an input string.
|
|
7
|
+
* @param input The input to extract the step number from.
|
|
8
|
+
* @returns The extracted step number.
|
|
9
|
+
*/
|
|
10
|
+
function extractNumber(input) {
|
|
11
|
+
invariant(input.includes("step"), "Can't extract a valid step number since");
|
|
12
|
+
const extracted = input.replace("step", "");
|
|
13
|
+
invariant(/^\d+$/.test(extracted), `Invalid step format: "${input}"`);
|
|
14
|
+
return Number.parseInt(extracted, 10);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A factory function to get the data of a specific step.
|
|
18
|
+
* @param resolvedStepValues The resolved step values.
|
|
19
|
+
* @returns A function to get specific step data from a target step.
|
|
20
|
+
*/
|
|
21
|
+
function getStep(resolvedStepValues) {
|
|
22
|
+
/**
|
|
23
|
+
* Gets the step data associated with the target step number.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const result = getStep(resolvedStepValues)({ step: 1 });
|
|
27
|
+
* // result: { step: 1, data: ... }
|
|
28
|
+
*
|
|
29
|
+
* @returns An object containing the `step` number and the associated step data.
|
|
30
|
+
*/
|
|
31
|
+
return function(options) {
|
|
32
|
+
const { step } = options;
|
|
33
|
+
return {
|
|
34
|
+
step,
|
|
35
|
+
data: resolvedStepValues[`step${step}`]
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function createCtxHelper(values, data) {
|
|
40
|
+
return data.reduce((acc, curr) => {
|
|
41
|
+
const stepNumber = extractNumber(curr);
|
|
42
|
+
const { data: data$1 } = getStep(values)({ step: stepNumber });
|
|
43
|
+
for (const [key, value] of Object.entries(data$1)) {
|
|
44
|
+
if (typeof value === "function" && key !== "update") continue;
|
|
45
|
+
data$1[key] = value;
|
|
46
|
+
}
|
|
47
|
+
acc[curr] = data$1;
|
|
48
|
+
return acc;
|
|
49
|
+
}, {});
|
|
50
|
+
}
|
|
51
|
+
function createCtx(values, stepData) {
|
|
52
|
+
const formatter = new Intl.ListFormat("en", {
|
|
53
|
+
style: "long",
|
|
54
|
+
type: "disjunction"
|
|
55
|
+
});
|
|
56
|
+
const validStepKeys = Object.keys(values);
|
|
57
|
+
const baseErrorMessage = () => {
|
|
58
|
+
return `"stepData" must be set to an array of available steps (${formatter.format(validStepKeys)})`;
|
|
59
|
+
};
|
|
60
|
+
if (stepData === "all") {
|
|
61
|
+
let ctx = {};
|
|
62
|
+
for (const key of validStepKeys) ctx = {
|
|
63
|
+
...ctx,
|
|
64
|
+
[key]: getStep(values)({ step: extractNumber(key) })
|
|
65
|
+
};
|
|
66
|
+
return createCtxHelper(values, validStepKeys);
|
|
67
|
+
}
|
|
68
|
+
if (Array.isArray(stepData)) {
|
|
69
|
+
invariant(stepData.every((step) => validStepKeys.includes(step)), () => {
|
|
70
|
+
const comparedResults = comparePartialArray(stepData, validStepKeys.map((key) => extractNumber(key)), formatter);
|
|
71
|
+
if (comparedResults.status === "error") return `${baseErrorMessage()}. See errors:\n ${printErrors(comparedResults.errors)}`;
|
|
72
|
+
return baseErrorMessage();
|
|
73
|
+
});
|
|
74
|
+
return createCtxHelper(values, stepData);
|
|
75
|
+
}
|
|
76
|
+
if (typeof stepData === "object") {
|
|
77
|
+
const keys = Object.keys(stepData);
|
|
78
|
+
invariant(keys.every((key) => validStepKeys.includes(key)), () => {
|
|
79
|
+
const comparedResults = comparePartialArray(keys, validStepKeys, formatter);
|
|
80
|
+
if (comparedResults.status === "error") return `${baseErrorMessage()}. See errors:\n ${printErrors(comparedResults.errors)}`;
|
|
81
|
+
return baseErrorMessage();
|
|
82
|
+
});
|
|
83
|
+
return createCtxHelper(values, keys);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`${baseErrorMessage()} OR to "all"`);
|
|
86
|
+
}
|
|
87
|
+
function functionalUpdate(updater, input) {
|
|
88
|
+
if (typeof updater === "function") return updater(input);
|
|
89
|
+
return updater;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
export { createCtx, functionalUpdate, getStep };
|
|
94
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["data"],"sources":["../../src/steps/utils.ts"],"sourcesContent":["import { comparePartialArray, printErrors } from '@/utils/helpers';\nimport { invariant } from '@/utils/invariant';\nimport type {\n AnyResolvedStep,\n GetCurrentStep,\n HelperFnChosenSteps,\n HelperFnCtx,\n StepNumbers,\n Updater,\n} from './types';\n\nexport type GetStepOptions<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TStepNumber extends TStepNumbers\n> = { step: TStepNumber };\n\n/**\n * Gets the step number from an input string.\n * @param input The input to extract the step number from.\n * @returns The extracted step number.\n */\nexport function extractNumber(input: string) {\n invariant(input.includes('step'), \"Can't extract a valid step number since\");\n\n const extracted = input.replace('step', '');\n\n invariant(/^\\d+$/.test(extracted), `Invalid step format: \"${input}\"`);\n\n return Number.parseInt(extracted, 10);\n}\n\n/**\n * A factory function to get the data of a specific step.\n * @param resolvedStepValues The resolved step values.\n * @returns A function to get specific step data from a target step.\n */\nexport function getStep<\n resolvedStep extends AnyResolvedStep,\n stepNumbers extends StepNumbers<resolvedStep>\n>(resolvedStepValues: resolvedStep) {\n /**\n * Gets the step data associated with the target step number.\n *\n * @example\n * const result = getStep(resolvedStepValues)({ step: 1 });\n * // result: { step: 1, data: ... }\n *\n * @returns An object containing the `step` number and the associated step data.\n */\n return function <stepNumber extends stepNumbers>(\n options: GetStepOptions<resolvedStep, stepNumbers, stepNumber>\n ) {\n const { step } = options;\n const stepKey = `step${step}` as keyof typeof resolvedStepValues;\n\n const data = resolvedStepValues[stepKey] as GetCurrentStep<\n typeof resolvedStepValues,\n stepNumber\n >;\n\n return { step, data };\n };\n}\n\nfunction createCtxHelper<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>\n>(values: TResolvedStep, data: string[]) {\n return data.reduce((acc, curr) => {\n const stepNumber = extractNumber(curr);\n const { data } = getStep(values)({\n step: stepNumber as TStepNumbers,\n });\n\n for (const [key, value] of Object.entries(data)) {\n // console.log({ [key]: value });\n // Remove the functions from the data to comply with `StrippedResolvedStep`\n if (typeof value === 'function' && key !== 'update') {\n continue;\n }\n\n data[key as keyof typeof data] = value as never;\n }\n\n acc[curr as keyof typeof acc] = data as never;\n\n return acc;\n }, {} as HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps>);\n}\n\nexport function createCtx<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>\n>(values: TResolvedStep, stepData: TChosenSteps) {\n const formatter = new Intl.ListFormat('en', {\n style: 'long',\n type: 'disjunction',\n });\n const validStepKeys = Object.keys(values);\n\n const baseErrorMessage = () => {\n return `\"stepData\" must be set to an array of available steps (${formatter.format(\n validStepKeys\n )})`;\n };\n\n if (stepData === 'all') {\n let ctx = {} as HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps>;\n\n for (const key of validStepKeys) {\n ctx = {\n ...ctx,\n [key]: getStep(values)({\n step: extractNumber(key) as never,\n }),\n };\n }\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n validStepKeys\n );\n }\n\n if (Array.isArray(stepData)) {\n invariant(\n stepData.every((step) => validStepKeys.includes(step)),\n () => {\n const comparedResults = comparePartialArray(\n stepData,\n validStepKeys.map((key) => extractNumber(key)),\n formatter\n );\n\n if (comparedResults.status === 'error') {\n return `${baseErrorMessage()}. See errors:\\n ${printErrors(\n comparedResults.errors\n )}`;\n }\n\n return baseErrorMessage();\n }\n );\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n stepData\n );\n }\n\n if (typeof stepData === 'object') {\n const keys = Object.keys(stepData);\n\n invariant(\n keys.every((key) => validStepKeys.includes(key)),\n () => {\n const comparedResults = comparePartialArray(\n keys,\n validStepKeys,\n formatter\n );\n\n if (comparedResults.status === 'error') {\n return `${baseErrorMessage()}. See errors:\\n ${printErrors(\n comparedResults.errors\n )}`;\n }\n\n return baseErrorMessage();\n }\n );\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n keys\n );\n }\n\n throw new Error(`${baseErrorMessage()} OR to \"all\"`);\n}\n\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput\n) {\n if (typeof updater === 'function') {\n return (updater as (_: TInput) => TOutput)(input);\n }\n\n return updater;\n}\n"],"mappings":";;;;;;;;;AAsBA,SAAgB,cAAc,OAAe;AAC3C,WAAU,MAAM,SAAS,OAAO,EAAE,0CAA0C;CAE5E,MAAM,YAAY,MAAM,QAAQ,QAAQ,GAAG;AAE3C,WAAU,QAAQ,KAAK,UAAU,EAAE,yBAAyB,MAAM,GAAG;AAErE,QAAO,OAAO,SAAS,WAAW,GAAG;;;;;;;AAQvC,SAAgB,QAGd,oBAAkC;;;;;;;;;;AAUlC,QAAO,SACL,SACA;EACA,MAAM,EAAE,SAAS;AAQjB,SAAO;GAAE;GAAM,MALF,mBAFG,OAAO;GAOF;;;AAIzB,SAAS,gBAIP,QAAuB,MAAgB;AACvC,QAAO,KAAK,QAAQ,KAAK,SAAS;EAChC,MAAM,aAAa,cAAc,KAAK;EACtC,MAAM,EAAE,iBAAS,QAAQ,OAAO,CAAC,EAC/B,MAAM,YACP,CAAC;AAEF,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQA,OAAK,EAAE;AAG/C,OAAI,OAAO,UAAU,cAAc,QAAQ,SACzC;AAGF,UAAK,OAA4B;;AAGnC,MAAI,QAA4BA;AAEhC,SAAO;IACN,EAAE,CAA2D;;AAGlE,SAAgB,UAId,QAAuB,UAAwB;CAC/C,MAAM,YAAY,IAAI,KAAK,WAAW,MAAM;EAC1C,OAAO;EACP,MAAM;EACP,CAAC;CACF,MAAM,gBAAgB,OAAO,KAAK,OAAO;CAEzC,MAAM,yBAAyB;AAC7B,SAAO,0DAA0D,UAAU,OACzE,cACD,CAAC;;AAGJ,KAAI,aAAa,OAAO;EACtB,IAAI,MAAM,EAAE;AAEZ,OAAK,MAAM,OAAO,cAChB,OAAM;GACJ,GAAG;IACF,MAAM,QAAQ,OAAO,CAAC,EACrB,MAAM,cAAc,IAAI,EACzB,CAAC;GACH;AAGH,SAAO,gBACL,QACA,cACD;;AAGH,KAAI,MAAM,QAAQ,SAAS,EAAE;AAC3B,YACE,SAAS,OAAO,SAAS,cAAc,SAAS,KAAK,CAAC,QAChD;GACJ,MAAM,kBAAkB,oBACtB,UACA,cAAc,KAAK,QAAQ,cAAc,IAAI,CAAC,EAC9C,UACD;AAED,OAAI,gBAAgB,WAAW,QAC7B,QAAO,GAAG,kBAAkB,CAAC,kBAAkB,YAC7C,gBAAgB,OACjB;AAGH,UAAO,kBAAkB;IAE5B;AAED,SAAO,gBACL,QACA,SACD;;AAGH,KAAI,OAAO,aAAa,UAAU;EAChC,MAAM,OAAO,OAAO,KAAK,SAAS;AAElC,YACE,KAAK,OAAO,QAAQ,cAAc,SAAS,IAAI,CAAC,QAC1C;GACJ,MAAM,kBAAkB,oBACtB,MACA,eACA,UACD;AAED,OAAI,gBAAgB,WAAW,QAC7B,QAAO,GAAG,kBAAkB,CAAC,kBAAkB,YAC7C,gBAAgB,OACjB;AAGH,UAAO,kBAAkB;IAE5B;AAED,SAAO,gBACL,QACA,KACD;;AAGH,OAAM,IAAI,MAAM,GAAG,kBAAkB,CAAC,cAAc;;AAGtD,SAAgB,iBACd,SACA,OACA;AACA,KAAI,OAAO,YAAY,WACrB,QAAQ,QAAmC,MAAM;AAGnD,QAAO"}
|
package/dist/storage.cjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const require_invariant = require('./utils/invariant.cjs');
|
|
2
|
+
const require_logger = require('./utils/logger.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/storage.ts
|
|
5
|
+
const WINDOW_UNDEFINED_MESSAGE = "\"window\" in undefined. No storage is available";
|
|
6
|
+
const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
7
|
+
var MultiStepFormStorage = class {
|
|
8
|
+
key;
|
|
9
|
+
store;
|
|
10
|
+
data;
|
|
11
|
+
log;
|
|
12
|
+
shouldRunActions;
|
|
13
|
+
throwWhenUndefined;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
const { key, data, store, throwWhenUndefined = false } = config;
|
|
16
|
+
this.log = new require_logger.MultiStepFormLogger({ prefix: DEFAULT_STORAGE_KEY });
|
|
17
|
+
this.key = key;
|
|
18
|
+
this.data = data;
|
|
19
|
+
this.throwWhenUndefined = throwWhenUndefined;
|
|
20
|
+
if (store) {
|
|
21
|
+
this.store = store;
|
|
22
|
+
this.shouldRunActions = true;
|
|
23
|
+
if (typeof window === "undefined") this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
24
|
+
} else if (typeof window !== "undefined") {
|
|
25
|
+
this.store = window.localStorage;
|
|
26
|
+
this.shouldRunActions = true;
|
|
27
|
+
} else {
|
|
28
|
+
this.shouldRunActions = false;
|
|
29
|
+
this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
throwOnEmptyStore() {
|
|
33
|
+
if (!this.throwWhenUndefined) return;
|
|
34
|
+
require_invariant.invariant(this.store, () => {
|
|
35
|
+
if (this.shouldRunActions) return WINDOW_UNDEFINED_MESSAGE;
|
|
36
|
+
return "No storage available";
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
resolveValue(value) {
|
|
40
|
+
if (typeof value === "function") return value(this.data);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
hasKey() {
|
|
44
|
+
return this.store.getItem(this.key) !== null;
|
|
45
|
+
}
|
|
46
|
+
get() {
|
|
47
|
+
this.throwOnEmptyStore();
|
|
48
|
+
if (!this.shouldRunActions) return;
|
|
49
|
+
const item = this.store.getItem(this.key);
|
|
50
|
+
if (item) return JSON.parse(item);
|
|
51
|
+
}
|
|
52
|
+
remove() {
|
|
53
|
+
this.throwOnEmptyStore();
|
|
54
|
+
if (!this.shouldRunActions) return;
|
|
55
|
+
this.store.removeItem(this.key);
|
|
56
|
+
}
|
|
57
|
+
add(value) {
|
|
58
|
+
this.throwOnEmptyStore();
|
|
59
|
+
if (!this.shouldRunActions) return;
|
|
60
|
+
const resolvedValue = JSON.stringify(this.resolveValue(value));
|
|
61
|
+
this.store.setItem(this.key, resolvedValue);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
exports.DEFAULT_STORAGE_KEY = DEFAULT_STORAGE_KEY;
|
|
67
|
+
exports.MultiStepFormStorage = MultiStepFormStorage;
|
|
68
|
+
//# sourceMappingURL=storage.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.cjs","names":["MultiStepFormLogger"],"sources":["../src/storage.ts"],"sourcesContent":["import type { Updater } from '@/steps/types';\nimport { invariant } from '@/utils/invariant';\nimport { MultiStepFormLogger } from '@/utils/logger';\n\nexport type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;\nexport type StorageConfig<TData, TKey extends string> = {\n key: TKey;\n data: TData;\n store?: Storage;\n /**\n * An extra option to throw an error when {@linkcode window} is `undefined`\n * @default false\n */\n throwWhenUndefined?: boolean;\n};\n\nconst WINDOW_UNDEFINED_MESSAGE =\n '\"window\" in undefined. No storage is available';\nexport const DEFAULT_STORAGE_KEY = 'MultiStepForm';\n\nexport class MultiStepFormStorage<\n data,\n key extends string = DefaultStorageKey\n> {\n readonly key: key;\n readonly store!: Storage;\n readonly data: data;\n private readonly log: MultiStepFormLogger;\n private readonly shouldRunActions: boolean;\n private readonly throwWhenUndefined: boolean;\n\n constructor(config: StorageConfig<data, key>) {\n const { key, data, store, throwWhenUndefined = false } = config;\n\n this.log = new MultiStepFormLogger({\n prefix: DEFAULT_STORAGE_KEY,\n });\n this.key = key;\n this.data = data;\n this.throwWhenUndefined = throwWhenUndefined;\n\n if (store) {\n this.store = store;\n this.shouldRunActions = true;\n\n if (typeof window === 'undefined') {\n // this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n } else if (typeof window !== 'undefined') {\n this.store = window.localStorage;\n this.shouldRunActions = true;\n } else {\n this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n }\n\n private throwOnEmptyStore() {\n if (!this.throwWhenUndefined) {\n return;\n }\n\n invariant(this.store, () => {\n if (this.shouldRunActions) {\n return WINDOW_UNDEFINED_MESSAGE;\n }\n\n return 'No storage available';\n });\n }\n\n private resolveValue(value: Updater<data>) {\n if (typeof value === 'function') {\n return (value as (input: data) => data)(this.data);\n }\n\n return value;\n }\n\n hasKey() {\n return this.store.getItem(this.key) !== null;\n }\n\n get() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const item = this.store.getItem(this.key);\n\n if (item) {\n const parsed = JSON.parse(item);\n\n return parsed as data;\n }\n }\n\n remove() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n this.store.removeItem(this.key);\n }\n\n add(value: Updater<data>) {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const resolvedValue = JSON.stringify(this.resolveValue(value));\n\n this.store.setItem(this.key, resolvedValue);\n }\n}\n"],"mappings":";;;;AAgBA,MAAM,2BACJ;AACF,MAAa,sBAAsB;AAEnC,IAAa,uBAAb,MAGE;CACA,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,QAAkC;EAC5C,MAAM,EAAE,KAAK,MAAM,OAAO,qBAAqB,UAAU;AAEzD,OAAK,MAAM,IAAIA,mCAAoB,EACjC,QAAQ,qBACT,CAAC;AACF,OAAK,MAAM;AACX,OAAK,OAAO;AACZ,OAAK,qBAAqB;AAE1B,MAAI,OAAO;AACT,QAAK,QAAQ;AACb,QAAK,mBAAmB;AAExB,OAAI,OAAO,WAAW,YAEpB,MAAK,IAAI,KAAK,yBAAyB;aAEhC,OAAO,WAAW,aAAa;AACxC,QAAK,QAAQ,OAAO;AACpB,QAAK,mBAAmB;SACnB;AACL,QAAK,mBAAmB;AACxB,QAAK,IAAI,KAAK,yBAAyB;;;CAI3C,AAAQ,oBAAoB;AAC1B,MAAI,CAAC,KAAK,mBACR;AAGF,8BAAU,KAAK,aAAa;AAC1B,OAAI,KAAK,iBACP,QAAO;AAGT,UAAO;IACP;;CAGJ,AAAQ,aAAa,OAAsB;AACzC,MAAI,OAAO,UAAU,WACnB,QAAQ,MAAgC,KAAK,KAAK;AAGpD,SAAO;;CAGT,SAAS;AACP,SAAO,KAAK,MAAM,QAAQ,KAAK,IAAI,KAAK;;CAG1C,MAAM;AACJ,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,OAAO,KAAK,MAAM,QAAQ,KAAK,IAAI;AAEzC,MAAI,KAGF,QAFe,KAAK,MAAM,KAAK;;CAMnC,SAAS;AACP,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;AAGF,OAAK,MAAM,WAAW,KAAK,IAAI;;CAGjC,IAAI,OAAsB;AACxB,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,gBAAgB,KAAK,UAAU,KAAK,aAAa,MAAM,CAAC;AAE9D,OAAK,MAAM,QAAQ,KAAK,KAAK,cAAc"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Updater } from "./steps/types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/storage.d.ts
|
|
4
|
+
type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;
|
|
5
|
+
type StorageConfig<TData, TKey extends string> = {
|
|
6
|
+
key: TKey;
|
|
7
|
+
data: TData;
|
|
8
|
+
store?: Storage;
|
|
9
|
+
/**
|
|
10
|
+
* An extra option to throw an error when {@linkcode window} is `undefined`
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
throwWhenUndefined?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
16
|
+
declare class MultiStepFormStorage<data, key extends string = DefaultStorageKey> {
|
|
17
|
+
readonly key: key;
|
|
18
|
+
readonly store: Storage;
|
|
19
|
+
readonly data: data;
|
|
20
|
+
private readonly log;
|
|
21
|
+
private readonly shouldRunActions;
|
|
22
|
+
private readonly throwWhenUndefined;
|
|
23
|
+
constructor(config: StorageConfig<data, key>);
|
|
24
|
+
private throwOnEmptyStore;
|
|
25
|
+
private resolveValue;
|
|
26
|
+
hasKey(): boolean;
|
|
27
|
+
get(): data | undefined;
|
|
28
|
+
remove(): void;
|
|
29
|
+
add(value: Updater<data>): void;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { DEFAULT_STORAGE_KEY, DefaultStorageKey, MultiStepFormStorage, StorageConfig };
|
|
33
|
+
//# sourceMappingURL=storage.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.cts","names":[],"sources":["../src/storage.ts"],"sourcesContent":[],"mappings":";;;KAIY,iBAAA,UAA2B;KAC3B;EADA,GAAA,EAEL,IAFK;EACA,IAAA,EAEJ,KAFI;EACL,KAAA,CAAA,EAEG,OAFH;EACC;;;AAWR;EAEa,kBAAA,CAAA,EAAA,OAAoB;CAEV;AAEP,cANH,mBAAA,GAMG,eAAA;AACG,cALN,oBAKM,CAAA,IAAA,EAAA,YAAA,MAAA,GAHI,iBAGJ,CAAA,CAAA;EACF,SAAA,GAAA,EAFD,GAEC;EAKmB,SAAA,KAAA,EANjB,OAMiB;EAAM,SAAA,IAAA,EALzB,IAKyB;EAApB,iBAAA,GAAA;EAqDjB,iBAAA,gBAAA;EA0BgB,iBAAA,kBAAA;EAAR,WAAA,CAAA,MAAA,EA/ES,aA+ET,CA/EuB,IA+EvB,EA/E6B,GA+E7B,CAAA;EAAO,QAAA,iBAAA;;;SA1Bf;;aA0BQ,QAAQ"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Updater } from "./steps/types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/storage.d.ts
|
|
4
|
+
type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;
|
|
5
|
+
type StorageConfig<TData, TKey extends string> = {
|
|
6
|
+
key: TKey;
|
|
7
|
+
data: TData;
|
|
8
|
+
store?: Storage;
|
|
9
|
+
/**
|
|
10
|
+
* An extra option to throw an error when {@linkcode window} is `undefined`
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
throwWhenUndefined?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
16
|
+
declare class MultiStepFormStorage<data, key extends string = DefaultStorageKey> {
|
|
17
|
+
readonly key: key;
|
|
18
|
+
readonly store: Storage;
|
|
19
|
+
readonly data: data;
|
|
20
|
+
private readonly log;
|
|
21
|
+
private readonly shouldRunActions;
|
|
22
|
+
private readonly throwWhenUndefined;
|
|
23
|
+
constructor(config: StorageConfig<data, key>);
|
|
24
|
+
private throwOnEmptyStore;
|
|
25
|
+
private resolveValue;
|
|
26
|
+
hasKey(): boolean;
|
|
27
|
+
get(): data | undefined;
|
|
28
|
+
remove(): void;
|
|
29
|
+
add(value: Updater<data>): void;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { DEFAULT_STORAGE_KEY, DefaultStorageKey, MultiStepFormStorage, StorageConfig };
|
|
33
|
+
//# sourceMappingURL=storage.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.mts","names":[],"sources":["../src/storage.ts"],"sourcesContent":[],"mappings":";;;KAIY,iBAAA,UAA2B;KAC3B;EADA,GAAA,EAEL,IAFK;EACA,IAAA,EAEJ,KAFI;EACL,KAAA,CAAA,EAEG,OAFH;EACC;;;AAWR;EAEa,kBAAA,CAAA,EAAA,OAAoB;CAEV;AAEP,cANH,mBAAA,GAMG,eAAA;AACG,cALN,oBAKM,CAAA,IAAA,EAAA,YAAA,MAAA,GAHI,iBAGJ,CAAA,CAAA;EACF,SAAA,GAAA,EAFD,GAEC;EAKmB,SAAA,KAAA,EANjB,OAMiB;EAAM,SAAA,IAAA,EALzB,IAKyB;EAApB,iBAAA,GAAA;EAqDjB,iBAAA,gBAAA;EA0BgB,iBAAA,kBAAA;EAAR,WAAA,CAAA,MAAA,EA/ES,aA+ET,CA/EuB,IA+EvB,EA/E6B,GA+E7B,CAAA;EAAO,QAAA,iBAAA;;;SA1Bf;;aA0BQ,QAAQ"}
|
package/dist/storage.mjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { invariant } from "./utils/invariant.mjs";
|
|
2
|
+
import { MultiStepFormLogger } from "./utils/logger.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/storage.ts
|
|
5
|
+
const WINDOW_UNDEFINED_MESSAGE = "\"window\" in undefined. No storage is available";
|
|
6
|
+
const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
7
|
+
var MultiStepFormStorage = class {
|
|
8
|
+
key;
|
|
9
|
+
store;
|
|
10
|
+
data;
|
|
11
|
+
log;
|
|
12
|
+
shouldRunActions;
|
|
13
|
+
throwWhenUndefined;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
const { key, data, store, throwWhenUndefined = false } = config;
|
|
16
|
+
this.log = new MultiStepFormLogger({ prefix: DEFAULT_STORAGE_KEY });
|
|
17
|
+
this.key = key;
|
|
18
|
+
this.data = data;
|
|
19
|
+
this.throwWhenUndefined = throwWhenUndefined;
|
|
20
|
+
if (store) {
|
|
21
|
+
this.store = store;
|
|
22
|
+
this.shouldRunActions = true;
|
|
23
|
+
if (typeof window === "undefined") this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
24
|
+
} else if (typeof window !== "undefined") {
|
|
25
|
+
this.store = window.localStorage;
|
|
26
|
+
this.shouldRunActions = true;
|
|
27
|
+
} else {
|
|
28
|
+
this.shouldRunActions = false;
|
|
29
|
+
this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
throwOnEmptyStore() {
|
|
33
|
+
if (!this.throwWhenUndefined) return;
|
|
34
|
+
invariant(this.store, () => {
|
|
35
|
+
if (this.shouldRunActions) return WINDOW_UNDEFINED_MESSAGE;
|
|
36
|
+
return "No storage available";
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
resolveValue(value) {
|
|
40
|
+
if (typeof value === "function") return value(this.data);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
hasKey() {
|
|
44
|
+
return this.store.getItem(this.key) !== null;
|
|
45
|
+
}
|
|
46
|
+
get() {
|
|
47
|
+
this.throwOnEmptyStore();
|
|
48
|
+
if (!this.shouldRunActions) return;
|
|
49
|
+
const item = this.store.getItem(this.key);
|
|
50
|
+
if (item) return JSON.parse(item);
|
|
51
|
+
}
|
|
52
|
+
remove() {
|
|
53
|
+
this.throwOnEmptyStore();
|
|
54
|
+
if (!this.shouldRunActions) return;
|
|
55
|
+
this.store.removeItem(this.key);
|
|
56
|
+
}
|
|
57
|
+
add(value) {
|
|
58
|
+
this.throwOnEmptyStore();
|
|
59
|
+
if (!this.shouldRunActions) return;
|
|
60
|
+
const resolvedValue = JSON.stringify(this.resolveValue(value));
|
|
61
|
+
this.store.setItem(this.key, resolvedValue);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
export { DEFAULT_STORAGE_KEY, MultiStepFormStorage };
|
|
67
|
+
//# sourceMappingURL=storage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.mjs","names":[],"sources":["../src/storage.ts"],"sourcesContent":["import type { Updater } from '@/steps/types';\nimport { invariant } from '@/utils/invariant';\nimport { MultiStepFormLogger } from '@/utils/logger';\n\nexport type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;\nexport type StorageConfig<TData, TKey extends string> = {\n key: TKey;\n data: TData;\n store?: Storage;\n /**\n * An extra option to throw an error when {@linkcode window} is `undefined`\n * @default false\n */\n throwWhenUndefined?: boolean;\n};\n\nconst WINDOW_UNDEFINED_MESSAGE =\n '\"window\" in undefined. No storage is available';\nexport const DEFAULT_STORAGE_KEY = 'MultiStepForm';\n\nexport class MultiStepFormStorage<\n data,\n key extends string = DefaultStorageKey\n> {\n readonly key: key;\n readonly store!: Storage;\n readonly data: data;\n private readonly log: MultiStepFormLogger;\n private readonly shouldRunActions: boolean;\n private readonly throwWhenUndefined: boolean;\n\n constructor(config: StorageConfig<data, key>) {\n const { key, data, store, throwWhenUndefined = false } = config;\n\n this.log = new MultiStepFormLogger({\n prefix: DEFAULT_STORAGE_KEY,\n });\n this.key = key;\n this.data = data;\n this.throwWhenUndefined = throwWhenUndefined;\n\n if (store) {\n this.store = store;\n this.shouldRunActions = true;\n\n if (typeof window === 'undefined') {\n // this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n } else if (typeof window !== 'undefined') {\n this.store = window.localStorage;\n this.shouldRunActions = true;\n } else {\n this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n }\n\n private throwOnEmptyStore() {\n if (!this.throwWhenUndefined) {\n return;\n }\n\n invariant(this.store, () => {\n if (this.shouldRunActions) {\n return WINDOW_UNDEFINED_MESSAGE;\n }\n\n return 'No storage available';\n });\n }\n\n private resolveValue(value: Updater<data>) {\n if (typeof value === 'function') {\n return (value as (input: data) => data)(this.data);\n }\n\n return value;\n }\n\n hasKey() {\n return this.store.getItem(this.key) !== null;\n }\n\n get() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const item = this.store.getItem(this.key);\n\n if (item) {\n const parsed = JSON.parse(item);\n\n return parsed as data;\n }\n }\n\n remove() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n this.store.removeItem(this.key);\n }\n\n add(value: Updater<data>) {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const resolvedValue = JSON.stringify(this.resolveValue(value));\n\n this.store.setItem(this.key, resolvedValue);\n }\n}\n"],"mappings":";;;;AAgBA,MAAM,2BACJ;AACF,MAAa,sBAAsB;AAEnC,IAAa,uBAAb,MAGE;CACA,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,QAAkC;EAC5C,MAAM,EAAE,KAAK,MAAM,OAAO,qBAAqB,UAAU;AAEzD,OAAK,MAAM,IAAI,oBAAoB,EACjC,QAAQ,qBACT,CAAC;AACF,OAAK,MAAM;AACX,OAAK,OAAO;AACZ,OAAK,qBAAqB;AAE1B,MAAI,OAAO;AACT,QAAK,QAAQ;AACb,QAAK,mBAAmB;AAExB,OAAI,OAAO,WAAW,YAEpB,MAAK,IAAI,KAAK,yBAAyB;aAEhC,OAAO,WAAW,aAAa;AACxC,QAAK,QAAQ,OAAO;AACpB,QAAK,mBAAmB;SACnB;AACL,QAAK,mBAAmB;AACxB,QAAK,IAAI,KAAK,yBAAyB;;;CAI3C,AAAQ,oBAAoB;AAC1B,MAAI,CAAC,KAAK,mBACR;AAGF,YAAU,KAAK,aAAa;AAC1B,OAAI,KAAK,iBACP,QAAO;AAGT,UAAO;IACP;;CAGJ,AAAQ,aAAa,OAAsB;AACzC,MAAI,OAAO,UAAU,WACnB,QAAQ,MAAgC,KAAK,KAAK;AAGpD,SAAO;;CAGT,SAAS;AACP,SAAO,KAAK,MAAM,QAAQ,KAAK,IAAI,KAAK;;CAG1C,MAAM;AACJ,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,OAAO,KAAK,MAAM,QAAQ,KAAK,IAAI;AAEzC,MAAI,KAGF,QAFe,KAAK,MAAM,KAAK;;CAMnC,SAAS;AACP,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;AAGF,OAAK,MAAM,WAAW,KAAK,IAAI;;CAGjC,IAAI,OAAsB;AACxB,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,gBAAgB,KAAK,UAAU,KAAK,aAAa,MAAM,CAAC;AAE9D,OAAK,MAAM,QAAQ,KAAK,KAAK,cAAc"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/subscribable.ts
|
|
3
|
+
var Subscribable = class {
|
|
4
|
+
listeners = /* @__PURE__ */ new Set();
|
|
5
|
+
constructor() {
|
|
6
|
+
this.subscribe = this.subscribe.bind(this);
|
|
7
|
+
}
|
|
8
|
+
subscribe(listener) {
|
|
9
|
+
this.listeners.add(listener);
|
|
10
|
+
this.onSubscribe();
|
|
11
|
+
return () => {
|
|
12
|
+
this.listeners.delete(listener);
|
|
13
|
+
this.onUnsubscribe();
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
hasListeners() {
|
|
17
|
+
return this.listeners.size > 0;
|
|
18
|
+
}
|
|
19
|
+
onSubscribe() {}
|
|
20
|
+
onUnsubscribe() {}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
exports.Subscribable = Subscribable;
|
|
25
|
+
//# sourceMappingURL=subscribable.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.cjs","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":["export abstract class Subscribable<TListener extends Function> {\n protected listeners = new Set<TListener>();\n\n constructor() {\n this.subscribe = this.subscribe.bind(this);\n }\n\n subscribe(listener: TListener) {\n this.listeners.add(listener);\n\n this.onSubscribe();\n\n return () => {\n this.listeners.delete(listener);\n this.onUnsubscribe();\n };\n }\n\n hasListeners() {\n return this.listeners.size > 0;\n }\n\n protected onSubscribe() {}\n protected onUnsubscribe() {}\n protected abstract notify(): void;\n abstract getSnapshot(): this;\n}\n"],"mappings":";;AAAA,IAAsB,eAAtB,MAA+D;CAC7D,AAAU,4BAAY,IAAI,KAAgB;CAE1C,cAAc;AACZ,OAAK,YAAY,KAAK,UAAU,KAAK,KAAK;;CAG5C,UAAU,UAAqB;AAC7B,OAAK,UAAU,IAAI,SAAS;AAE5B,OAAK,aAAa;AAElB,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;AAC/B,QAAK,eAAe;;;CAIxB,eAAe;AACb,SAAO,KAAK,UAAU,OAAO;;CAG/B,AAAU,cAAc;CACxB,AAAU,gBAAgB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/subscribable.d.ts
|
|
2
|
+
declare abstract class Subscribable<TListener extends Function> {
|
|
3
|
+
protected listeners: Set<TListener>;
|
|
4
|
+
constructor();
|
|
5
|
+
subscribe(listener: TListener): () => void;
|
|
6
|
+
hasListeners(): boolean;
|
|
7
|
+
protected onSubscribe(): void;
|
|
8
|
+
protected onUnsubscribe(): void;
|
|
9
|
+
protected abstract notify(): void;
|
|
10
|
+
abstract getSnapshot(): this;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Subscribable };
|
|
14
|
+
//# sourceMappingURL=subscribable.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.d.cts","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":[],"mappings":";uBAAsB,+BAA+B;EAA/B,UAAA,SAAY,EACb,GADa,CACb,SADa,CAAA;EAAmB,WAAA,CAAA;EAChC,SAAA,CAAA,QAAA,EAMC,SAND,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,YAAA,CAAA,CAAA,EAAA,OAAA;EAMC,UAAA,WAAA,CAAA,CAAA,EAAA,IAAA;EAAS,UAAA,aAAA,CAAA,CAAA,EAAA,IAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/subscribable.d.ts
|
|
2
|
+
declare abstract class Subscribable<TListener extends Function> {
|
|
3
|
+
protected listeners: Set<TListener>;
|
|
4
|
+
constructor();
|
|
5
|
+
subscribe(listener: TListener): () => void;
|
|
6
|
+
hasListeners(): boolean;
|
|
7
|
+
protected onSubscribe(): void;
|
|
8
|
+
protected onUnsubscribe(): void;
|
|
9
|
+
protected abstract notify(): void;
|
|
10
|
+
abstract getSnapshot(): this;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Subscribable };
|
|
14
|
+
//# sourceMappingURL=subscribable.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.d.mts","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":[],"mappings":";uBAAsB,+BAA+B;EAA/B,UAAA,SAAY,EACb,GADa,CACb,SADa,CAAA;EAAmB,WAAA,CAAA;EAChC,SAAA,CAAA,QAAA,EAMC,SAND,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,YAAA,CAAA,CAAA,EAAA,OAAA;EAMC,UAAA,WAAA,CAAA,CAAA,EAAA,IAAA;EAAS,UAAA,aAAA,CAAA,CAAA,EAAA,IAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/subscribable.ts
|
|
2
|
+
var Subscribable = class {
|
|
3
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4
|
+
constructor() {
|
|
5
|
+
this.subscribe = this.subscribe.bind(this);
|
|
6
|
+
}
|
|
7
|
+
subscribe(listener) {
|
|
8
|
+
this.listeners.add(listener);
|
|
9
|
+
this.onSubscribe();
|
|
10
|
+
return () => {
|
|
11
|
+
this.listeners.delete(listener);
|
|
12
|
+
this.onUnsubscribe();
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
hasListeners() {
|
|
16
|
+
return this.listeners.size > 0;
|
|
17
|
+
}
|
|
18
|
+
onSubscribe() {}
|
|
19
|
+
onUnsubscribe() {}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Subscribable };
|
|
24
|
+
//# sourceMappingURL=subscribable.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.mjs","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":["export abstract class Subscribable<TListener extends Function> {\n protected listeners = new Set<TListener>();\n\n constructor() {\n this.subscribe = this.subscribe.bind(this);\n }\n\n subscribe(listener: TListener) {\n this.listeners.add(listener);\n\n this.onSubscribe();\n\n return () => {\n this.listeners.delete(listener);\n this.onUnsubscribe();\n };\n }\n\n hasListeners() {\n return this.listeners.size > 0;\n }\n\n protected onSubscribe() {}\n protected onUnsubscribe() {}\n protected abstract notify(): void;\n abstract getSnapshot(): this;\n}\n"],"mappings":";AAAA,IAAsB,eAAtB,MAA+D;CAC7D,AAAU,4BAAY,IAAI,KAAgB;CAE1C,cAAc;AACZ,OAAK,YAAY,KAAK,UAAU,KAAK,KAAK;;CAG5C,UAAU,UAAqB;AAC7B,OAAK,UAAU,IAAI,SAAS;AAE5B,OAAK,aAAa;AAElB,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;AAC/B,QAAK,eAAe;;;CAIxB,eAAe;AACb,SAAO,KAAK,UAAU,OAAO;;CAG/B,AAAU,cAAc;CACxB,AAAU,gBAAgB"}
|