valyrian.js 8.1.6 → 8.1.7
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/lib/pulses/index.d.ts +6 -5
- package/dist/lib/pulses/index.d.ts.map +1 -1
- package/dist/pulses/index.js +20 -22
- package/dist/pulses/index.js.map +2 -2
- package/dist/pulses/index.min.js +1 -1
- package/dist/pulses/index.min.js.map +1 -1
- package/dist/pulses/index.mjs +20 -22
- package/dist/pulses/index.mjs.map +2 -2
- package/lib/pulses/index.ts +36 -44
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
type State = Record<string, any>;
|
|
2
|
-
export type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export type PulseContext = {
|
|
3
|
+
$flush: () => Promise<void>;
|
|
4
|
+
};
|
|
5
|
+
export type Pulse<StateType, TReturn = unknown> = (this: PulseContext, state: StateType, ...args: any[]) => TReturn | Promise<TReturn>;
|
|
6
|
+
export type Pulses<StateType> = Record<string, Pulse<StateType, any>>;
|
|
6
7
|
type ProxyState<StateType> = StateType & {
|
|
7
8
|
[key: string]: any;
|
|
8
9
|
};
|
|
9
10
|
type StorePulses<PulsesType extends Pulses<any>> = {
|
|
10
|
-
[K in keyof PulsesType]: PulsesType[K] extends (state: any, ...args: infer Args) => infer R ? (...args: Args) => R : never;
|
|
11
|
+
[K in keyof PulsesType]: PulsesType[K] extends (this: any, state: any, ...args: infer Args) => infer R ? (...args: Args) => R : never;
|
|
11
12
|
};
|
|
12
13
|
export declare function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(initialState: StateType, pulses: PulsesType): StorePulses<PulsesType> & {
|
|
13
14
|
state: ProxyState<StateType>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/pulses/index.ts"],"names":[],"mappings":"AAIA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEjC,MAAM,MAAM,KAAK,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/pulses/index.ts"],"names":[],"mappings":"AAIA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,KAAK,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,IAAI,CAChD,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,SAAS,EAChB,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,MAAM,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;AAEtE,KAAK,UAAU,CAAC,SAAS,IAAI,SAAS,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC;AAIhE,KAAK,WAAW,CAAC,UAAU,SAAS,MAAM,CAAC,GAAG,CAAC,IAAI;KAChD,CAAC,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,IAAI,KAAK,MAAM,CAAC,GAClG,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GACpB,KAAK;CACV,CAAC;AAmOF,wBAAgB,gBAAgB,CAAC,SAAS,SAAS,KAAK,EAAE,UAAU,SAAS,MAAM,CAAC,SAAS,CAAC,EAC5F,YAAY,EAAE,SAAS,EACvB,MAAM,EAAE,UAAU;;QA/Ld,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI;SAC1C,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI;EAiMjD;AAED,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,KAAK,EAAE,UAAU,SAAS,MAAM,CAAC,SAAS,CAAC,EAC9F,YAAY,EAAE,SAAS,EACvB,MAAM,EAAE,UAAU;;QAtMd,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI;SAC1C,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI;EA2MjD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,QAU5C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC,CA4BlH"}
|
package/dist/pulses/index.js
CHANGED
|
@@ -135,12 +135,13 @@ function createStore(initialState, pulses, immutable = false) {
|
|
|
135
135
|
if (currentState === null) {
|
|
136
136
|
currentState = (0, import_utils.deepCloneUnfreeze)(localState);
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
this.$flush = async () => {
|
|
139
|
+
if (currentState) {
|
|
140
|
+
setState(currentState, true);
|
|
141
|
+
currentState = (0, import_utils.deepCloneUnfreeze)(localState);
|
|
142
|
+
}
|
|
141
143
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
142
144
|
};
|
|
143
|
-
Reflect.set(this, "$flush", $flush);
|
|
144
145
|
const emptyFlush = async () => {
|
|
145
146
|
};
|
|
146
147
|
try {
|
|
@@ -148,16 +149,16 @@ function createStore(initialState, pulses, immutable = false) {
|
|
|
148
149
|
if (pulseResult instanceof Promise) {
|
|
149
150
|
return pulseResult.then((resolvedValue) => {
|
|
150
151
|
setState(currentState);
|
|
151
|
-
|
|
152
|
+
this.$flush = emptyFlush;
|
|
152
153
|
return resolvedValue;
|
|
153
154
|
}).catch((error) => {
|
|
154
155
|
console.error(`Error in pulse '${key}':`, error);
|
|
155
|
-
|
|
156
|
+
this.$flush = emptyFlush;
|
|
156
157
|
throw error;
|
|
157
158
|
});
|
|
158
159
|
} else {
|
|
159
160
|
setState(currentState);
|
|
160
|
-
|
|
161
|
+
this.$flush = emptyFlush;
|
|
161
162
|
return pulseResult;
|
|
162
163
|
}
|
|
163
164
|
} catch (error) {
|
|
@@ -199,20 +200,17 @@ function createStore(initialState, pulses, immutable = false) {
|
|
|
199
200
|
throw new Error(`Pulse '${prop}' does not exist`);
|
|
200
201
|
}
|
|
201
202
|
const pulseMethod = pulses2[prop];
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
return pulseMethod;
|
|
203
|
+
return (...args) => {
|
|
204
|
+
const result = pulseMethod.apply(pulseMethod, args);
|
|
205
|
+
if (result instanceof Promise) {
|
|
206
|
+
return result.then((r) => {
|
|
207
|
+
trigger("pulse", prop, args);
|
|
208
|
+
return r;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
trigger("pulse", prop, args);
|
|
212
|
+
return result;
|
|
213
|
+
};
|
|
216
214
|
}
|
|
217
215
|
});
|
|
218
216
|
return pulsesProxy;
|
|
@@ -222,7 +220,7 @@ function createPulseStore(initialState, pulses) {
|
|
|
222
220
|
}
|
|
223
221
|
function createMutableStore(initialState, pulses) {
|
|
224
222
|
console.warn(
|
|
225
|
-
"Warning: You are working with a mutable state.
|
|
223
|
+
"Warning: You are working with a mutable state. All state changes made outside of a pulse will not trigger a re-render."
|
|
226
224
|
);
|
|
227
225
|
return createStore(initialState, pulses, false);
|
|
228
226
|
}
|
package/dist/pulses/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../lib/pulses/index.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-console */\nimport { updateVnode, VnodeWithDom, current, DomElement } from \"valyrian.js\";\nimport { deepCloneUnfreeze, deepFreeze, hasChanged } from \"valyrian.js/utils\";\n\ntype State = Record<string, any>;\n\nexport type Pulse<StateType, TReturn = unknown> = (state: StateType, ...args: any[]) => TReturn | Promise<TReturn>;\n\nexport type Pulses<StateType> = Record<string, Pulse<StateType, any> & { $flush?: () => Promise<void> }>;\n\ntype ProxyState<StateType> = StateType & { [key: string]: any };\n\nconst effectStack: Function[] = [];\n\ntype StorePulses<PulsesType extends Pulses<any>> = {\n [K in keyof PulsesType]: PulsesType[K] extends (state: any, ...args: infer Args) => infer R\n ? (...args: Args) => R\n : never;\n};\n\n/** Funci\u00F3n auxiliar para registrar la suscripci\u00F3n al nodo DOM.\n * Retorna true si se agreg\u00F3 la suscripci\u00F3n, o false si se encontr\u00F3 un nodo padre ya suscrito.\n */\nfunction registerDomSubscription(subscribers: Set<Function>, domWithVnodesToUpdate: WeakSet<DomElement>): void {\n const currentVnode = current.vnode as VnodeWithDom;\n if (!currentVnode || domWithVnodesToUpdate.has(currentVnode.dom)) {\n return;\n }\n\n let hasParent = false;\n let parent = currentVnode.dom.parentElement as DomElement;\n while (parent) {\n if (domWithVnodesToUpdate.has(parent)) {\n hasParent = true;\n break;\n }\n parent = parent.parentElement as DomElement;\n }\n\n // Si no hay nodo padre registrado, se crea la suscripci\u00F3n.\n if (!hasParent) {\n const dom = currentVnode.dom;\n const subscription = () => {\n updateVnode(dom.vnode);\n if (!dom.parentElement) {\n subscribers.delete(subscription);\n domWithVnodesToUpdate.delete(dom);\n }\n };\n subscribers.add(subscription);\n domWithVnodesToUpdate.add(dom);\n }\n}\n\nfunction createStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType | (() => StateType) | null,\n pulses: PulsesType,\n immutable = false\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const boundPulses: Pulses<StateType> = {};\n for (const key in pulses) {\n if (typeof pulses[key] !== \"function\") {\n throw new Error(`Pulse '${key}' must be a function`);\n }\n if (key === \"state\") {\n throw new Error(`A pulse cannot be named 'state'`);\n }\n boundPulses[key] = getPulseMethod(key);\n }\n\n const localState: StateType =\n (typeof initialState === \"function\" ? initialState() : initialState) || ({} as StateType);\n\n function isMutable() {\n if (immutable) {\n throw new Error(\"You need to call a pulse to modify the state\");\n }\n }\n\n let currentState: StateType | null = null;\n let pulseCallCount = 0;\n\n const proxyState = new Proxy(localState, {\n get: (state, prop: string) => {\n // If we are in a pulse, we return the value of the cloned state.\n if (currentState) {\n return currentState[prop];\n }\n\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n\n return state[prop];\n },\n set: (state, prop: string, value: any) => {\n isMutable();\n Reflect.set(state, prop, value);\n return true;\n },\n deleteProperty: (state, prop: string) => {\n isMutable();\n Reflect.deleteProperty(state, prop);\n return true;\n }\n });\n\n function syncState(newState: StateType) {\n for (const key in newState) {\n localState[key] = immutable ? deepFreeze(newState[key]) : newState[key];\n }\n for (const key in localState) {\n if (!(key in newState)) {\n Reflect.deleteProperty(localState, key);\n }\n }\n }\n\n let debounceTimeout: ReturnType<typeof setTimeout> | null = null;\n function debouncedUpdate() {\n if (debounceTimeout) {\n clearTimeout(debounceTimeout);\n }\n debounceTimeout = setTimeout(() => subscribers.forEach((subscriber) => subscriber()), 0);\n }\n\n function setState(newState: StateType, flush = false) {\n pulseCallCount--;\n if (!hasChanged(localState, newState)) {\n return;\n }\n if (pulseCallCount > 0 && !flush) {\n return;\n }\n syncState(newState);\n currentState = null;\n debouncedUpdate();\n }\n\n function getPulseMethod(key: string) {\n function pulseMethod(this: Pulse<StateType, any> & { $flush: () => Promise<void> }, ...args: any[]) {\n pulseCallCount++;\n if (currentState === null) {\n currentState = deepCloneUnfreeze(localState);\n }\n\n const $flush = async () => {\n setState(currentState as StateType, true);\n currentState = deepCloneUnfreeze(localState);\n await new Promise((resolve) => setTimeout(resolve, 0));\n };\n\n Reflect.set(this, \"$flush\", $flush);\n const emptyFlush = async () => {};\n\n try {\n const pulseResult = pulses[key].apply(this, [currentState, ...args] as any);\n if (pulseResult instanceof Promise) {\n return pulseResult\n .then((resolvedValue) => {\n setState(currentState as StateType);\n Reflect.set(this, \"$flush\", emptyFlush);\n return resolvedValue;\n })\n .catch((error) => {\n console.error(`Error in pulse '${key}':`, error);\n Reflect.set(this, \"$flush\", emptyFlush);\n throw error;\n });\n } else {\n setState(currentState);\n Reflect.set(this, \"$flush\", emptyFlush);\n return pulseResult;\n }\n } catch (error) {\n console.error(`Error in pulse '${key}':`, error);\n Reflect.set(this, \"$flush\", emptyFlush);\n throw error;\n }\n }\n\n return pulseMethod;\n }\n\n syncState(localState);\n\n const listeners: Record<string, Function[]> = {};\n const trigger = (event: string, ...args: any[]) => {\n if (listeners[event]) {\n listeners[event].forEach((callback) => callback(...args));\n }\n };\n\n const pulsesProxy = new Proxy(boundPulses, {\n get: (pulses, prop: string) => {\n if (prop === \"state\") {\n return proxyState;\n }\n if (prop === \"on\") {\n return (event: string, callback: Function) => {\n if (!listeners[event]) {\n listeners[event] = [];\n }\n listeners[event].push(callback);\n };\n }\n if (prop === \"off\") {\n return (event: string, callback: Function) => {\n if (listeners[event]) {\n listeners[event] = listeners[event].filter((cb) => cb !== callback);\n }\n };\n }\n if (!(prop in pulses)) {\n throw new Error(`Pulse '${prop}' does not exist`);\n }\n const pulseMethod = pulses[prop];\n\n if (typeof pulseMethod === \"function\") {\n return (...args: any[]) => {\n const result = pulseMethod.apply(pulsesProxy, args as any);\n if (result instanceof Promise) {\n return result.then((r) => {\n trigger(\"pulse\", prop, args);\n return r;\n });\n }\n trigger(\"pulse\", prop, args);\n return result;\n };\n }\n\n return pulseMethod;\n }\n });\n\n return pulsesProxy as StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n };\n}\n\nexport function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n return createStore(initialState, pulses, true);\n}\n\nexport function createMutableStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n console.warn(\n \"Warning: You are working with a mutable state. This can lead to unpredictable behavior. All state changes made outside of a pulse will not trigger a re-render.\"\n );\n return createStore(initialState, pulses, false);\n}\n\nexport function createEffect(effect: Function) {\n const runEffect = () => {\n try {\n effectStack.push(runEffect);\n effect();\n } finally {\n effectStack.pop();\n }\n };\n runEffect();\n}\n\nexport function createPulse<T>(initialValue: T): [() => T, (newValue: T | ((current: T) => T)) => void, () => void] {\n let value = initialValue;\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const runSubscribers = () => {\n subscribers.forEach((subscriber) => subscriber());\n };\n\n const read = (): T => {\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n return value;\n };\n\n const write = (newValue: T | ((current: T) => T)): void => {\n const resolvedValue = typeof newValue === \"function\" ? (newValue as (current: T) => T)(value) : newValue;\n if (!hasChanged(value, resolvedValue)) {\n return;\n }\n value = resolvedValue;\n runSubscribers();\n };\n\n return [read, write, runSubscribers];\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAA+D;AAC/D,mBAA0D;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-console */\nimport { updateVnode, VnodeWithDom, current, DomElement } from \"valyrian.js\";\nimport { deepCloneUnfreeze, deepFreeze, hasChanged } from \"valyrian.js/utils\";\n\ntype State = Record<string, any>;\n\nexport type PulseContext = {\n $flush: () => Promise<void>;\n};\n\nexport type Pulse<StateType, TReturn = unknown> = (\n this: PulseContext,\n state: StateType,\n ...args: any[]\n) => TReturn | Promise<TReturn>;\n\nexport type Pulses<StateType> = Record<string, Pulse<StateType, any>>;\n\ntype ProxyState<StateType> = StateType & { [key: string]: any };\n\nconst effectStack: Function[] = [];\n\ntype StorePulses<PulsesType extends Pulses<any>> = {\n [K in keyof PulsesType]: PulsesType[K] extends (this: any, state: any, ...args: infer Args) => infer R\n ? (...args: Args) => R\n : never;\n};\n\nfunction registerDomSubscription(subscribers: Set<Function>, domWithVnodesToUpdate: WeakSet<DomElement>): void {\n const currentVnode = current.vnode as VnodeWithDom;\n if (!currentVnode || domWithVnodesToUpdate.has(currentVnode.dom)) {\n return;\n }\n\n let hasParent = false;\n let parent = currentVnode.dom.parentElement as DomElement;\n while (parent) {\n if (domWithVnodesToUpdate.has(parent)) {\n hasParent = true;\n break;\n }\n parent = parent.parentElement as DomElement;\n }\n\n if (!hasParent) {\n const dom = currentVnode.dom;\n const subscription = () => {\n updateVnode(dom.vnode);\n if (!dom.parentElement) {\n subscribers.delete(subscription);\n domWithVnodesToUpdate.delete(dom);\n }\n };\n subscribers.add(subscription);\n domWithVnodesToUpdate.add(dom);\n }\n}\n\nfunction createStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType | (() => StateType) | null,\n pulses: PulsesType,\n immutable = false\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const boundPulses: Record<string, Function> = {};\n for (const key in pulses) {\n if (typeof pulses[key] !== \"function\") {\n throw new Error(`Pulse '${key}' must be a function`);\n }\n if (key === \"state\") {\n throw new Error(`A pulse cannot be named 'state'`);\n }\n boundPulses[key] = getPulseMethod(key);\n }\n\n const localState: StateType =\n (typeof initialState === \"function\" ? initialState() : initialState) || ({} as StateType);\n\n function isMutable() {\n if (immutable) {\n throw new Error(\"You need to call a pulse to modify the state\");\n }\n }\n\n let currentState: StateType | null = null;\n let pulseCallCount = 0;\n\n const proxyState = new Proxy(localState, {\n get: (state, prop: string) => {\n if (currentState) {\n return currentState[prop];\n }\n\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n\n return state[prop];\n },\n set: (state, prop: string, value: any) => {\n isMutable();\n Reflect.set(state, prop, value);\n return true;\n },\n deleteProperty: (state, prop: string) => {\n isMutable();\n Reflect.deleteProperty(state, prop);\n return true;\n }\n });\n\n function syncState(newState: StateType) {\n for (const key in newState) {\n localState[key] = immutable ? deepFreeze(newState[key]) : newState[key];\n }\n for (const key in localState) {\n if (!(key in newState)) {\n Reflect.deleteProperty(localState, key);\n }\n }\n }\n\n let debounceTimeout: ReturnType<typeof setTimeout> | null = null;\n function debouncedUpdate() {\n if (debounceTimeout) {\n clearTimeout(debounceTimeout);\n }\n debounceTimeout = setTimeout(() => subscribers.forEach((subscriber) => subscriber()), 0);\n }\n\n function setState(newState: StateType, flush = false) {\n pulseCallCount--;\n if (!hasChanged(localState, newState)) {\n return;\n }\n if (pulseCallCount > 0 && !flush) {\n return;\n }\n syncState(newState);\n currentState = null;\n debouncedUpdate();\n }\n\n function getPulseMethod(key: string) {\n function pulseMethod(this: PulseContext, ...args: any[]) {\n pulseCallCount++;\n if (currentState === null) {\n currentState = deepCloneUnfreeze(localState);\n }\n\n this.$flush = async () => {\n if (currentState) {\n setState(currentState, true);\n currentState = deepCloneUnfreeze(localState);\n }\n await new Promise((resolve) => setTimeout(resolve, 0));\n };\n\n const emptyFlush = async () => {};\n\n try {\n const pulseResult = pulses[key].apply(this, [currentState, ...args]);\n if (pulseResult instanceof Promise) {\n return pulseResult\n .then((resolvedValue) => {\n setState(currentState as StateType);\n this.$flush = emptyFlush;\n return resolvedValue;\n })\n .catch((error) => {\n console.error(`Error in pulse '${key}':`, error);\n this.$flush = emptyFlush;\n throw error;\n });\n } else {\n setState(currentState);\n this.$flush = emptyFlush;\n return pulseResult;\n }\n } catch (error) {\n console.error(`Error in pulse '${key}':`, error);\n Reflect.set(this, \"$flush\", emptyFlush);\n throw error;\n }\n }\n\n return pulseMethod;\n }\n\n syncState(localState);\n\n const listeners: Record<string, Function[]> = {};\n const trigger = (event: string, ...args: any[]) => {\n if (listeners[event]) {\n listeners[event].forEach((callback) => callback(...args));\n }\n };\n\n const pulsesProxy = new Proxy(boundPulses, {\n get: (pulses, prop: string) => {\n if (prop === \"state\") {\n return proxyState;\n }\n if (prop === \"on\") {\n return (event: string, callback: Function) => {\n if (!listeners[event]) {\n listeners[event] = [];\n }\n listeners[event].push(callback);\n };\n }\n if (prop === \"off\") {\n return (event: string, callback: Function) => {\n if (listeners[event]) {\n listeners[event] = listeners[event].filter((cb) => cb !== callback);\n }\n };\n }\n if (!(prop in pulses)) {\n throw new Error(`Pulse '${prop}' does not exist`);\n }\n const pulseMethod = pulses[prop];\n\n return (...args: any[]) => {\n const result = pulseMethod.apply(pulseMethod, args);\n if (result instanceof Promise) {\n return result.then((r) => {\n trigger(\"pulse\", prop, args);\n return r;\n });\n }\n trigger(\"pulse\", prop, args);\n return result;\n };\n }\n });\n\n return pulsesProxy as StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n };\n}\n\nexport function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n) {\n return createStore(initialState, pulses, true);\n}\n\nexport function createMutableStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n) {\n console.warn(\n \"Warning: You are working with a mutable state. All state changes made outside of a pulse will not trigger a re-render.\"\n );\n return createStore(initialState, pulses, false);\n}\n\nexport function createEffect(effect: Function) {\n const runEffect = () => {\n try {\n effectStack.push(runEffect);\n effect();\n } finally {\n effectStack.pop();\n }\n };\n runEffect();\n}\n\nexport function createPulse<T>(initialValue: T): [() => T, (newValue: T | ((current: T) => T)) => void, () => void] {\n let value = initialValue;\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const runSubscribers = () => {\n subscribers.forEach((subscriber) => subscriber());\n };\n\n const read = (): T => {\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n return value;\n };\n\n const write = (newValue: T | ((current: T) => T)): void => {\n const resolvedValue = typeof newValue === \"function\" ? (newValue as (current: T) => T)(value) : newValue;\n if (!hasChanged(value, resolvedValue)) {\n return;\n }\n value = resolvedValue;\n runSubscribers();\n };\n\n return [read, write, runSubscribers];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["pulses"]
|
|
7
7
|
}
|
package/dist/pulses/index.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,o={};((t,n)=>{for(var r in n)e(t,r,{get:n[r],enumerable:!0})})(o,{createEffect:()=>d,createMutableStore:()=>p,createPulse:()=>y,createPulseStore:()=>h});var s,
|
|
1
|
+
(()=>{"use strict";var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,o={};((t,n)=>{for(var r in n)e(t,r,{get:n[r],enumerable:!0})})(o,{createEffect:()=>d,createMutableStore:()=>p,createPulse:()=>y,createPulseStore:()=>h});var s,u=(s=o,((o,s,u,l)=>{if(s&&"object"==typeof s||"function"==typeof s)for(let a of n(s))r.call(o,a)||a===u||e(o,a,{get:()=>s[a],enumerable:!(l=t(s,a))||l.enumerable});return o})(e({},"__esModule",{value:!0}),s)),l=require("valyrian.js"),a=require("valyrian.js/utils"),i=[];function c(e,t){const n=l.current.vnode;if(!n||t.has(n.dom))return;let r=!1,o=n.dom.parentElement;for(;o;){if(t.has(o)){r=!0;break}o=o.parentElement}if(!r){const r=n.dom,o=()=>{(0,l.updateVnode)(r.vnode),r.parentElement||(e.delete(o),t.delete(r))};e.add(o),t.add(r)}}function f(e,t,n=!1){const r=new Set,o=new WeakSet,s={};for(const e in t){if("function"!=typeof t[e])throw new Error(`Pulse '${e}' must be a function`);if("state"===e)throw new Error("A pulse cannot be named 'state'");s[e]=m(e)}const u=("function"==typeof e?e():e)||{};function l(){if(n)throw new Error("You need to call a pulse to modify the state")}let f=null,h=0;const p=new Proxy(u,{get:(e,t)=>{if(f)return f[t];const n=i[i.length-1];return n&&!r.has(n)&&r.add(n),c(r,o),e[t]},set:(e,t,n)=>(l(),Reflect.set(e,t,n),!0),deleteProperty:(e,t)=>(l(),Reflect.deleteProperty(e,t),!0)});function d(e){for(const t in e)u[t]=n?(0,a.deepFreeze)(e[t]):e[t];for(const t in u)t in e||Reflect.deleteProperty(u,t)}let y=null;function w(e,t=!1){h--,(0,a.hasChanged)(u,e)&&(h>0&&!t||(d(e),f=null,y&&clearTimeout(y),y=setTimeout(()=>r.forEach(e=>e()),0)))}function m(e){return function(...n){h++,null===f&&(f=(0,a.deepCloneUnfreeze)(u)),this.$flush=async()=>{f&&(w(f,!0),f=(0,a.deepCloneUnfreeze)(u)),await new Promise(e=>setTimeout(e,0))};const r=async()=>{};try{const o=t[e].apply(this,[f,...n]);return o instanceof Promise?o.then(e=>(w(f),this.$flush=r,e)).catch(t=>{throw console.error(`Error in pulse '${e}':`,t),this.$flush=r,t}):(w(f),this.$flush=r,o)}catch(t){throw console.error(`Error in pulse '${e}':`,t),Reflect.set(this,"$flush",r),t}}}d(u);const P={},g=(e,...t)=>{P[e]&&P[e].forEach(e=>e(...t))};return new Proxy(s,{get:(e,t)=>{if("state"===t)return p;if("on"===t)return(e,t)=>{P[e]||(P[e]=[]),P[e].push(t)};if("off"===t)return(e,t)=>{P[e]&&(P[e]=P[e].filter(e=>e!==t))};if(!(t in e))throw new Error(`Pulse '${t}' does not exist`);const n=e[t];return(...e)=>{const r=n.apply(n,e);return r instanceof Promise?r.then(n=>(g("pulse",t,e),n)):(g("pulse",t,e),r)}}})}function h(e,t){return f(e,t,!0)}function p(e,t){return console.warn("Warning: You are working with a mutable state. All state changes made outside of a pulse will not trigger a re-render."),f(e,t,!1)}function d(e){const t=()=>{try{i.push(t),e()}finally{i.pop()}};t()}function y(e){let t=e;const n=new Set,r=new WeakSet,o=()=>{n.forEach(e=>e())};return[()=>{const e=i[i.length-1];return e&&!n.has(e)&&n.add(e),c(n,r),t},e=>{const n="function"==typeof e?e(t):e;(0,a.hasChanged)(t,n)&&(t=n,o())},o]}"undefined"!=typeof module?module.exports=u:self.ValyrianPulses=u})();//# sourceMappingURL=index.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpbmRleF9leHBvcnRzIiwiX19leHBvcnQiLCJjcmVhdGVFZmZlY3QiLCJjcmVhdGVNdXRhYmxlU3RvcmUiLCJjcmVhdGVQdWxzZSIsImNyZWF0ZVB1bHNlU3RvcmUiLCJfX0VYUE9SVFNfXyIsImltcG9ydF92YWx5cmlhbiIsInJlcXVpcmUiLCJpbXBvcnRfdXRpbHMiLCJlZmZlY3RTdGFjayIsInJlZ2lzdGVyRG9tU3Vic2NyaXB0aW9uIiwic3Vic2NyaWJlcnMiLCJkb21XaXRoVm5vZGVzVG9VcGRhdGUiLCJjdXJyZW50Vm5vZGUiLCJjdXJyZW50Iiwidm5vZGUiLCJoYXMiLCJkb20iLCJoYXNQYXJlbnQiLCJwYXJlbnQiLCJwYXJlbnRFbGVtZW50Iiwic3Vic2NyaXB0aW9uIiwidXBkYXRlVm5vZGUiLCJkZWxldGUiLCJhZGQiLCJjcmVhdGVTdG9yZSIsImluaXRpYWxTdGF0ZSIsInB1bHNlcyIsImltbXV0YWJsZSIsIlNldCIsIldlYWtTZXQiLCJib3VuZFB1bHNlcyIsImtleSIsIkVycm9yIiwiZ2V0UHVsc2VNZXRob2QiLCJsb2NhbFN0YXRlIiwiaXNNdXRhYmxlIiwiY3VycmVudFN0YXRlIiwicHVsc2VDYWxsQ291bnQiLCJwcm94eVN0YXRlIiwiUHJveHkiLCJnZXQiLCJzdGF0ZSIsInByb3AiLCJjdXJyZW50RWZmZWN0IiwibGVuZ3RoIiwic2V0IiwidmFsdWUiLCJSZWZsZWN0IiwiZGVsZXRlUHJvcGVydHkiLCJzeW5jU3RhdGUiLCJuZXdTdGF0ZSIsImRlZXBGcmVlemUiLCJkZWJvdW5jZVRpbWVvdXQiLCJzZXRTdGF0ZSIsImZsdXNoIiwiaGFzQ2hhbmdlZCIsImNsZWFyVGltZW91dCIsInNldFRpbWVvdXQiLCJmb3JFYWNoIiwic3Vic2NyaWJlciIsImFyZ3MiLCJkZWVwQ2xvbmVVbmZyZWV6ZSIsInRoaXMiLCJhc3luYyIsIlByb21pc2UiLCJyZXNvbHZlIiwiZW1wdHlGbHVzaCIsInB1bHNlUmVzdWx0IiwiYXBwbHkiLCJ0aGVuIiwicmVzb2x2ZWRWYWx1ZSIsImNhdGNoIiwiZXJyb3IiLCJjb25zb2xlIiwibGlzdGVuZXJzIiwidHJpZ2dlciIsImV2ZW50IiwiY2FsbGJhY2siLCJwdWxzZXNQcm94eSIsInB1c2giLCJmaWx0ZXIiLCJjYiIsInB1bHNlTWV0aG9kIiwicmVzdWx0IiwiciIsIndhcm4iLCJlZmZlY3QiLCJydW5FZmZlY3QiLCJwb3AiLCJpbml0aWFsVmFsdWUiLCJydW5TdWJzY3JpYmVycyIsIm5ld1ZhbHVlIl0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3B1bHNlcy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyB1cGRhdGVWbm9kZSwgVm5vZGVXaXRoRG9tLCBjdXJyZW50LCBEb21FbGVtZW50IH0gZnJvbSBcInZhbHlyaWFuLmpzXCI7XG5pbXBvcnQgeyBkZWVwQ2xvbmVVbmZyZWV6ZSwgZGVlcEZyZWV6ZSwgaGFzQ2hhbmdlZCB9IGZyb20gXCJ2YWx5cmlhbi5qcy91dGlsc1wiO1xuXG50eXBlIFN0YXRlID0gUmVjb3JkPHN0cmluZywgYW55PjtcblxuZXhwb3J0IHR5cGUgUHVsc2U8U3RhdGVUeXBlLCBUUmV0dXJuID0gdW5rbm93bj4gPSAoc3RhdGU6IFN0YXRlVHlwZSwgLi4uYXJnczogYW55W10pID0+IFRSZXR1cm4gfCBQcm9taXNlPFRSZXR1cm4+O1xuXG5leHBvcnQgdHlwZSBQdWxzZXM8U3RhdGVUeXBlPiA9IFJlY29yZDxzdHJpbmcsIFB1bHNlPFN0YXRlVHlwZSwgYW55PiAmIHsgJGZsdXNoPzogKCkgPT4gUHJvbWlzZTx2b2lkPiB9PjtcblxudHlwZSBQcm94eVN0YXRlPFN0YXRlVHlwZT4gPSBTdGF0ZVR5cGUgJiB7IFtrZXk6IHN0cmluZ106IGFueSB9O1xuXG5jb25zdCBlZmZlY3RTdGFjazogRnVuY3Rpb25bXSA9IFtdO1xuXG50eXBlIFN0b3JlUHVsc2VzPFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8YW55Pj4gPSB7XG4gIFtLIGluIGtleW9mIFB1bHNlc1R5cGVdOiBQdWxzZXNUeXBlW0tdIGV4dGVuZHMgKHN0YXRlOiBhbnksIC4uLmFyZ3M6IGluZmVyIEFyZ3MpID0+IGluZmVyIFJcbiAgICA/ICguLi5hcmdzOiBBcmdzKSA9PiBSXG4gICAgOiBuZXZlcjtcbn07XG5cbi8qKiBGdW5jacOzbiBhdXhpbGlhciBwYXJhIHJlZ2lzdHJhciBsYSBzdXNjcmlwY2nDs24gYWwgbm9kbyBET00uXG4gKiAgUmV0b3JuYSB0cnVlIHNpIHNlIGFncmVnw7MgbGEgc3VzY3JpcGNpw7NuLCBvIGZhbHNlIHNpIHNlIGVuY29udHLDsyB1biBub2RvIHBhZHJlIHlhIHN1c2NyaXRvLlxuICovXG5mdW5jdGlvbiByZWdpc3RlckRvbVN1YnNjcmlwdGlvbihzdWJzY3JpYmVyczogU2V0PEZ1bmN0aW9uPiwgZG9tV2l0aFZub2Rlc1RvVXBkYXRlOiBXZWFrU2V0PERvbUVsZW1lbnQ+KTogdm9pZCB7XG4gIGNvbnN0IGN1cnJlbnRWbm9kZSA9IGN1cnJlbnQudm5vZGUgYXMgVm5vZGVXaXRoRG9tO1xuICBpZiAoIWN1cnJlbnRWbm9kZSB8fCBkb21XaXRoVm5vZGVzVG9VcGRhdGUuaGFzKGN1cnJlbnRWbm9kZS5kb20pKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IGhhc1BhcmVudCA9IGZhbHNlO1xuICBsZXQgcGFyZW50ID0gY3VycmVudFZub2RlLmRvbS5wYXJlbnRFbGVtZW50IGFzIERvbUVsZW1lbnQ7XG4gIHdoaWxlIChwYXJlbnQpIHtcbiAgICBpZiAoZG9tV2l0aFZub2Rlc1RvVXBkYXRlLmhhcyhwYXJlbnQpKSB7XG4gICAgICBoYXNQYXJlbnQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50IGFzIERvbUVsZW1lbnQ7XG4gIH1cblxuICAvLyBTaSBubyBoYXkgbm9kbyBwYWRyZSByZWdpc3RyYWRvLCBzZSBjcmVhIGxhIHN1c2NyaXBjacOzbi5cbiAgaWYgKCFoYXNQYXJlbnQpIHtcbiAgICBjb25zdCBkb20gPSBjdXJyZW50Vm5vZGUuZG9tO1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9ICgpID0+IHtcbiAgICAgIHVwZGF0ZVZub2RlKGRvbS52bm9kZSk7XG4gICAgICBpZiAoIWRvbS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgIHN1YnNjcmliZXJzLmRlbGV0ZShzdWJzY3JpcHRpb24pO1xuICAgICAgICBkb21XaXRoVm5vZGVzVG9VcGRhdGUuZGVsZXRlKGRvbSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBzdWJzY3JpYmVycy5hZGQoc3Vic2NyaXB0aW9uKTtcbiAgICBkb21XaXRoVm5vZGVzVG9VcGRhdGUuYWRkKGRvbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlU3RvcmU8U3RhdGVUeXBlIGV4dGVuZHMgU3RhdGUsIFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8U3RhdGVUeXBlPj4oXG4gIGluaXRpYWxTdGF0ZTogU3RhdGVUeXBlIHwgKCgpID0+IFN0YXRlVHlwZSkgfCBudWxsLFxuICBwdWxzZXM6IFB1bHNlc1R5cGUsXG4gIGltbXV0YWJsZSA9IGZhbHNlXG4pOiBTdG9yZVB1bHNlczxQdWxzZXNUeXBlPiAmIHtcbiAgc3RhdGU6IFByb3h5U3RhdGU8U3RhdGVUeXBlPjtcbiAgb246IChldmVudDogc3RyaW5nLCBjYWxsYmFjazogRnVuY3Rpb24pID0+IHZvaWQ7XG4gIG9mZjogKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4gdm9pZDtcbn0ge1xuICBjb25zdCBzdWJzY3JpYmVycyA9IG5ldyBTZXQ8RnVuY3Rpb24+KCk7XG4gIGNvbnN0IGRvbVdpdGhWbm9kZXNUb1VwZGF0ZSA9IG5ldyBXZWFrU2V0PERvbUVsZW1lbnQ+KCk7XG5cbiAgY29uc3QgYm91bmRQdWxzZXM6IFB1bHNlczxTdGF0ZVR5cGU+ID0ge307XG4gIGZvciAoY29uc3Qga2V5IGluIHB1bHNlcykge1xuICAgIGlmICh0eXBlb2YgcHVsc2VzW2tleV0gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQdWxzZSAnJHtrZXl9JyBtdXN0IGJlIGEgZnVuY3Rpb25gKTtcbiAgICB9XG4gICAgaWYgKGtleSA9PT0gXCJzdGF0ZVwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEEgcHVsc2UgY2Fubm90IGJlIG5hbWVkICdzdGF0ZSdgKTtcbiAgICB9XG4gICAgYm91bmRQdWxzZXNba2V5XSA9IGdldFB1bHNlTWV0aG9kKGtleSk7XG4gIH1cblxuICBjb25zdCBsb2NhbFN0YXRlOiBTdGF0ZVR5cGUgPVxuICAgICh0eXBlb2YgaW5pdGlhbFN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyBpbml0aWFsU3RhdGUoKSA6IGluaXRpYWxTdGF0ZSkgfHwgKHt9IGFzIFN0YXRlVHlwZSk7XG5cbiAgZnVuY3Rpb24gaXNNdXRhYmxlKCkge1xuICAgIGlmIChpbW11dGFibGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIllvdSBuZWVkIHRvIGNhbGwgYSBwdWxzZSB0byBtb2RpZnkgdGhlIHN0YXRlXCIpO1xuICAgIH1cbiAgfVxuXG4gIGxldCBjdXJyZW50U3RhdGU6IFN0YXRlVHlwZSB8IG51bGwgPSBudWxsO1xuICBsZXQgcHVsc2VDYWxsQ291bnQgPSAwO1xuXG4gIGNvbnN0IHByb3h5U3RhdGUgPSBuZXcgUHJveHkobG9jYWxTdGF0ZSwge1xuICAgIGdldDogKHN0YXRlLCBwcm9wOiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIElmIHdlIGFyZSBpbiBhIHB1bHNlLCB3ZSByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBjbG9uZWQgc3RhdGUuXG4gICAgICBpZiAoY3VycmVudFN0YXRlKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50U3RhdGVbcHJvcF07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGN1cnJlbnRFZmZlY3QgPSBlZmZlY3RTdGFja1tlZmZlY3RTdGFjay5sZW5ndGggLSAxXTtcbiAgICAgIGlmIChjdXJyZW50RWZmZWN0ICYmICFzdWJzY3JpYmVycy5oYXMoY3VycmVudEVmZmVjdCkpIHtcbiAgICAgICAgc3Vic2NyaWJlcnMuYWRkKGN1cnJlbnRFZmZlY3QpO1xuICAgICAgfVxuXG4gICAgICByZWdpc3RlckRvbVN1YnNjcmlwdGlvbihzdWJzY3JpYmVycywgZG9tV2l0aFZub2Rlc1RvVXBkYXRlKTtcblxuICAgICAgcmV0dXJuIHN0YXRlW3Byb3BdO1xuICAgIH0sXG4gICAgc2V0OiAoc3RhdGUsIHByb3A6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgaXNNdXRhYmxlKCk7XG4gICAgICBSZWZsZWN0LnNldChzdGF0ZSwgcHJvcCwgdmFsdWUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICBkZWxldGVQcm9wZXJ0eTogKHN0YXRlLCBwcm9wOiBzdHJpbmcpID0+IHtcbiAgICAgIGlzTXV0YWJsZSgpO1xuICAgICAgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eShzdGF0ZSwgcHJvcCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIHN5bmNTdGF0ZShuZXdTdGF0ZTogU3RhdGVUeXBlKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gbmV3U3RhdGUpIHtcbiAgICAgIGxvY2FsU3RhdGVba2V5XSA9IGltbXV0YWJsZSA/IGRlZXBGcmVlemUobmV3U3RhdGVba2V5XSkgOiBuZXdTdGF0ZVtrZXldO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBsb2NhbFN0YXRlKSB7XG4gICAgICBpZiAoIShrZXkgaW4gbmV3U3RhdGUpKSB7XG4gICAgICAgIFJlZmxlY3QuZGVsZXRlUHJvcGVydHkobG9jYWxTdGF0ZSwga2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgZGVib3VuY2VUaW1lb3V0OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBmdW5jdGlvbiBkZWJvdW5jZWRVcGRhdGUoKSB7XG4gICAgaWYgKGRlYm91bmNlVGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KGRlYm91bmNlVGltZW91dCk7XG4gICAgfVxuICAgIGRlYm91bmNlVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gc3Vic2NyaWJlcnMuZm9yRWFjaCgoc3Vic2NyaWJlcikgPT4gc3Vic2NyaWJlcigpKSwgMCk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTdGF0ZShuZXdTdGF0ZTogU3RhdGVUeXBlLCBmbHVzaCA9IGZhbHNlKSB7XG4gICAgcHVsc2VDYWxsQ291bnQtLTtcbiAgICBpZiAoIWhhc0NoYW5nZWQobG9jYWxTdGF0ZSwgbmV3U3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwdWxzZUNhbGxDb3VudCA+IDAgJiYgIWZsdXNoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN5bmNTdGF0ZShuZXdTdGF0ZSk7XG4gICAgY3VycmVudFN0YXRlID0gbnVsbDtcbiAgICBkZWJvdW5jZWRVcGRhdGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFB1bHNlTWV0aG9kKGtleTogc3RyaW5nKSB7XG4gICAgZnVuY3Rpb24gcHVsc2VNZXRob2QodGhpczogUHVsc2U8U3RhdGVUeXBlLCBhbnk+ICYgeyAkZmx1c2g6ICgpID0+IFByb21pc2U8dm9pZD4gfSwgLi4uYXJnczogYW55W10pIHtcbiAgICAgIHB1bHNlQ2FsbENvdW50Kys7XG4gICAgICBpZiAoY3VycmVudFN0YXRlID09PSBudWxsKSB7XG4gICAgICAgIGN1cnJlbnRTdGF0ZSA9IGRlZXBDbG9uZVVuZnJlZXplKGxvY2FsU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCAkZmx1c2ggPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNldFN0YXRlKGN1cnJlbnRTdGF0ZSBhcyBTdGF0ZVR5cGUsIHRydWUpO1xuICAgICAgICBjdXJyZW50U3RhdGUgPSBkZWVwQ2xvbmVVbmZyZWV6ZShsb2NhbFN0YXRlKTtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMCkpO1xuICAgICAgfTtcblxuICAgICAgUmVmbGVjdC5zZXQodGhpcywgXCIkZmx1c2hcIiwgJGZsdXNoKTtcbiAgICAgIGNvbnN0IGVtcHR5Rmx1c2ggPSBhc3luYyAoKSA9PiB7fTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcHVsc2VSZXN1bHQgPSBwdWxzZXNba2V5XS5hcHBseSh0aGlzLCBbY3VycmVudFN0YXRlLCAuLi5hcmdzXSBhcyBhbnkpO1xuICAgICAgICBpZiAocHVsc2VSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgcmV0dXJuIHB1bHNlUmVzdWx0XG4gICAgICAgICAgICAudGhlbigocmVzb2x2ZWRWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICBzZXRTdGF0ZShjdXJyZW50U3RhdGUgYXMgU3RhdGVUeXBlKTtcbiAgICAgICAgICAgICAgUmVmbGVjdC5zZXQodGhpcywgXCIkZmx1c2hcIiwgZW1wdHlGbHVzaCk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlZFZhbHVlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gcHVsc2UgJyR7a2V5fSc6YCwgZXJyb3IpO1xuICAgICAgICAgICAgICBSZWZsZWN0LnNldCh0aGlzLCBcIiRmbHVzaFwiLCBlbXB0eUZsdXNoKTtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRTdGF0ZShjdXJyZW50U3RhdGUpO1xuICAgICAgICAgIFJlZmxlY3Quc2V0KHRoaXMsIFwiJGZsdXNoXCIsIGVtcHR5Rmx1c2gpO1xuICAgICAgICAgIHJldHVybiBwdWxzZVJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gcHVsc2UgJyR7a2V5fSc6YCwgZXJyb3IpO1xuICAgICAgICBSZWZsZWN0LnNldCh0aGlzLCBcIiRmbHVzaFwiLCBlbXB0eUZsdXNoKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHB1bHNlTWV0aG9kO1xuICB9XG5cbiAgc3luY1N0YXRlKGxvY2FsU3RhdGUpO1xuXG4gIGNvbnN0IGxpc3RlbmVyczogUmVjb3JkPHN0cmluZywgRnVuY3Rpb25bXT4gPSB7fTtcbiAgY29uc3QgdHJpZ2dlciA9IChldmVudDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIGlmIChsaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICBsaXN0ZW5lcnNbZXZlbnRdLmZvckVhY2goKGNhbGxiYWNrKSA9PiBjYWxsYmFjayguLi5hcmdzKSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHB1bHNlc1Byb3h5ID0gbmV3IFByb3h5KGJvdW5kUHVsc2VzLCB7XG4gICAgZ2V0OiAocHVsc2VzLCBwcm9wOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChwcm9wID09PSBcInN0YXRlXCIpIHtcbiAgICAgICAgcmV0dXJuIHByb3h5U3RhdGU7XG4gICAgICB9XG4gICAgICBpZiAocHJvcCA9PT0gXCJvblwiKSB7XG4gICAgICAgIHJldHVybiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uKSA9PiB7XG4gICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnNbZXZlbnRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIGxpc3RlbmVyc1tldmVudF0ucHVzaChjYWxsYmFjayk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBpZiAocHJvcCA9PT0gXCJvZmZcIikge1xuICAgICAgICByZXR1cm4gKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4ge1xuICAgICAgICAgIGlmIChsaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnNbZXZlbnRdID0gbGlzdGVuZXJzW2V2ZW50XS5maWx0ZXIoKGNiKSA9PiBjYiAhPT0gY2FsbGJhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmICghKHByb3AgaW4gcHVsc2VzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFB1bHNlICcke3Byb3B9JyBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgfVxuICAgICAgY29uc3QgcHVsc2VNZXRob2QgPSBwdWxzZXNbcHJvcF07XG5cbiAgICAgIGlmICh0eXBlb2YgcHVsc2VNZXRob2QgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gcHVsc2VNZXRob2QuYXBwbHkocHVsc2VzUHJveHksIGFyZ3MgYXMgYW55KTtcbiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyKSA9PiB7XG4gICAgICAgICAgICAgIHRyaWdnZXIoXCJwdWxzZVwiLCBwcm9wLCBhcmdzKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHJpZ2dlcihcInB1bHNlXCIsIHByb3AsIGFyZ3MpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwdWxzZU1ldGhvZDtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwdWxzZXNQcm94eSBhcyBTdG9yZVB1bHNlczxQdWxzZXNUeXBlPiAmIHtcbiAgICBzdGF0ZTogUHJveHlTdGF0ZTxTdGF0ZVR5cGU+O1xuICAgIG9uOiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uKSA9PiB2b2lkO1xuICAgIG9mZjogKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4gdm9pZDtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVB1bHNlU3RvcmU8U3RhdGVUeXBlIGV4dGVuZHMgU3RhdGUsIFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8U3RhdGVUeXBlPj4oXG4gIGluaXRpYWxTdGF0ZTogU3RhdGVUeXBlLFxuICBwdWxzZXM6IFB1bHNlc1R5cGVcbik6IFN0b3JlUHVsc2VzPFB1bHNlc1R5cGU+ICYge1xuICBzdGF0ZTogUHJveHlTdGF0ZTxTdGF0ZVR5cGU+O1xuICBvbjogKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4gdm9pZDtcbiAgb2ZmOiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uKSA9PiB2b2lkO1xufSB7XG4gIHJldHVybiBjcmVhdGVTdG9yZShpbml0aWFsU3RhdGUsIHB1bHNlcywgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNdXRhYmxlU3RvcmU8U3RhdGVUeXBlIGV4dGVuZHMgU3RhdGUsIFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8U3RhdGVUeXBlPj4oXG4gIGluaXRpYWxTdGF0ZTogU3RhdGVUeXBlLFxuICBwdWxzZXM6IFB1bHNlc1R5cGVcbik6IFN0b3JlUHVsc2VzPFB1bHNlc1R5cGU+ICYge1xuICBzdGF0ZTogUHJveHlTdGF0ZTxTdGF0ZVR5cGU+O1xuICBvbjogKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4gdm9pZDtcbiAgb2ZmOiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uKSA9PiB2b2lkO1xufSB7XG4gIGNvbnNvbGUud2FybihcbiAgICBcIldhcm5pbmc6IFlvdSBhcmUgd29ya2luZyB3aXRoIGEgbXV0YWJsZSBzdGF0ZS4gVGhpcyBjYW4gbGVhZCB0byB1bnByZWRpY3RhYmxlIGJlaGF2aW9yLiBBbGwgc3RhdGUgY2hhbmdlcyBtYWRlIG91dHNpZGUgb2YgYSBwdWxzZSB3aWxsIG5vdCB0cmlnZ2VyIGEgcmUtcmVuZGVyLlwiXG4gICk7XG4gIHJldHVybiBjcmVhdGVTdG9yZShpbml0aWFsU3RhdGUsIHB1bHNlcywgZmFsc2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWZmZWN0KGVmZmVjdDogRnVuY3Rpb24pIHtcbiAgY29uc3QgcnVuRWZmZWN0ID0gKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBlZmZlY3RTdGFjay5wdXNoKHJ1bkVmZmVjdCk7XG4gICAgICBlZmZlY3QoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZWZmZWN0U3RhY2sucG9wKCk7XG4gICAgfVxuICB9O1xuICBydW5FZmZlY3QoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVB1bHNlPFQ+KGluaXRpYWxWYWx1ZTogVCk6IFsoKSA9PiBULCAobmV3VmFsdWU6IFQgfCAoKGN1cnJlbnQ6IFQpID0+IFQpKSA9PiB2b2lkLCAoKSA9PiB2b2lkXSB7XG4gIGxldCB2YWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgY29uc3Qgc3Vic2NyaWJlcnMgPSBuZXcgU2V0PEZ1bmN0aW9uPigpO1xuICBjb25zdCBkb21XaXRoVm5vZGVzVG9VcGRhdGUgPSBuZXcgV2Vha1NldDxEb21FbGVtZW50PigpO1xuXG4gIGNvbnN0IHJ1blN1YnNjcmliZXJzID0gKCkgPT4ge1xuICAgIHN1YnNjcmliZXJzLmZvckVhY2goKHN1YnNjcmliZXIpID0+IHN1YnNjcmliZXIoKSk7XG4gIH07XG5cbiAgY29uc3QgcmVhZCA9ICgpOiBUID0+IHtcbiAgICBjb25zdCBjdXJyZW50RWZmZWN0ID0gZWZmZWN0U3RhY2tbZWZmZWN0U3RhY2subGVuZ3RoIC0gMV07XG4gICAgaWYgKGN1cnJlbnRFZmZlY3QgJiYgIXN1YnNjcmliZXJzLmhhcyhjdXJyZW50RWZmZWN0KSkge1xuICAgICAgc3Vic2NyaWJlcnMuYWRkKGN1cnJlbnRFZmZlY3QpO1xuICAgIH1cbiAgICByZWdpc3RlckRvbVN1YnNjcmlwdGlvbihzdWJzY3JpYmVycywgZG9tV2l0aFZub2Rlc1RvVXBkYXRlKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgY29uc3Qgd3JpdGUgPSAobmV3VmFsdWU6IFQgfCAoKGN1cnJlbnQ6IFQpID0+IFQpKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVzb2x2ZWRWYWx1ZSA9IHR5cGVvZiBuZXdWYWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gKG5ld1ZhbHVlIGFzIChjdXJyZW50OiBUKSA9PiBUKSh2YWx1ZSkgOiBuZXdWYWx1ZTtcbiAgICBpZiAoIWhhc0NoYW5nZWQodmFsdWUsIHJlc29sdmVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhbHVlID0gcmVzb2x2ZWRWYWx1ZTtcbiAgICBydW5TdWJzY3JpYmVycygpO1xuICB9O1xuXG4gIHJldHVybiBbcmVhZCwgd3JpdGUsIHJ1blN1YnNjcmliZXJzXTtcbn1cbiJdLCJtYXBwaW5ncyI6ImdKQUFBQSxFQUFBLEcseURBQUFDLENBQUFELEVBQUEsQ0FBQUUsYUFBQSxJQUFBQSxFQUFBQyxtQkFBQSxJQUFBQSxFQUFBQyxZQUFBLElBQUFBLEVBQUFDLGlCQUFBLElBQUFBLElBQUEsSSxFQUFBQyxHLEVBQUFOLEUsME1BQ0FPLEVBQStEQyxRQUFBLGVBQy9EQyxFQUEwREQsUUFBQSxxQkFVcERFLEVBQTBCLEdBV2hDLFNBQVNDLEVBQXdCQyxFQUE0QkMsR0FDM0QsTUFBTUMsRUFBZVAsRUFBQVEsUUFBUUMsTUFDN0IsSUFBS0YsR0FBZ0JELEVBQXNCSSxJQUFJSCxFQUFhSSxLQUMxRCxPQUdGLElBQUlDLEdBQVksRUFDWkMsRUFBU04sRUFBYUksSUFBSUcsY0FDOUIsS0FBT0QsR0FBUSxDQUNiLEdBQUlQLEVBQXNCSSxJQUFJRyxHQUFTLENBQ3JDRCxHQUFZLEVBQ1osS0FDRixDQUNBQyxFQUFTQSxFQUFPQyxhQUNsQixDQUdB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
|
|
1
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpbmRleF9leHBvcnRzIiwiX19leHBvcnQiLCJjcmVhdGVFZmZlY3QiLCJjcmVhdGVNdXRhYmxlU3RvcmUiLCJjcmVhdGVQdWxzZSIsImNyZWF0ZVB1bHNlU3RvcmUiLCJfX0VYUE9SVFNfXyIsImltcG9ydF92YWx5cmlhbiIsInJlcXVpcmUiLCJpbXBvcnRfdXRpbHMiLCJlZmZlY3RTdGFjayIsInJlZ2lzdGVyRG9tU3Vic2NyaXB0aW9uIiwic3Vic2NyaWJlcnMiLCJkb21XaXRoVm5vZGVzVG9VcGRhdGUiLCJjdXJyZW50Vm5vZGUiLCJjdXJyZW50Iiwidm5vZGUiLCJoYXMiLCJkb20iLCJoYXNQYXJlbnQiLCJwYXJlbnQiLCJwYXJlbnRFbGVtZW50Iiwic3Vic2NyaXB0aW9uIiwidXBkYXRlVm5vZGUiLCJkZWxldGUiLCJhZGQiLCJjcmVhdGVTdG9yZSIsImluaXRpYWxTdGF0ZSIsInB1bHNlcyIsImltbXV0YWJsZSIsIlNldCIsIldlYWtTZXQiLCJib3VuZFB1bHNlcyIsImtleSIsIkVycm9yIiwiZ2V0UHVsc2VNZXRob2QiLCJsb2NhbFN0YXRlIiwiaXNNdXRhYmxlIiwiY3VycmVudFN0YXRlIiwicHVsc2VDYWxsQ291bnQiLCJwcm94eVN0YXRlIiwiUHJveHkiLCJnZXQiLCJzdGF0ZSIsInByb3AiLCJjdXJyZW50RWZmZWN0IiwibGVuZ3RoIiwic2V0IiwidmFsdWUiLCJSZWZsZWN0IiwiZGVsZXRlUHJvcGVydHkiLCJzeW5jU3RhdGUiLCJuZXdTdGF0ZSIsImRlZXBGcmVlemUiLCJkZWJvdW5jZVRpbWVvdXQiLCJzZXRTdGF0ZSIsImZsdXNoIiwiaGFzQ2hhbmdlZCIsImNsZWFyVGltZW91dCIsInNldFRpbWVvdXQiLCJmb3JFYWNoIiwic3Vic2NyaWJlciIsImFyZ3MiLCJkZWVwQ2xvbmVVbmZyZWV6ZSIsInRoaXMiLCIkZmx1c2giLCJhc3luYyIsIlByb21pc2UiLCJyZXNvbHZlIiwiZW1wdHlGbHVzaCIsInB1bHNlUmVzdWx0IiwiYXBwbHkiLCJ0aGVuIiwicmVzb2x2ZWRWYWx1ZSIsImNhdGNoIiwiZXJyb3IiLCJjb25zb2xlIiwibGlzdGVuZXJzIiwidHJpZ2dlciIsImV2ZW50IiwiY2FsbGJhY2siLCJwdXNoIiwiZmlsdGVyIiwiY2IiLCJwdWxzZU1ldGhvZCIsInJlc3VsdCIsInIiLCJ3YXJuIiwiZWZmZWN0IiwicnVuRWZmZWN0IiwicG9wIiwiaW5pdGlhbFZhbHVlIiwicnVuU3Vic2NyaWJlcnMiLCJuZXdWYWx1ZSJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9wdWxzZXMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0IHsgdXBkYXRlVm5vZGUsIFZub2RlV2l0aERvbSwgY3VycmVudCwgRG9tRWxlbWVudCB9IGZyb20gXCJ2YWx5cmlhbi5qc1wiO1xuaW1wb3J0IHsgZGVlcENsb25lVW5mcmVlemUsIGRlZXBGcmVlemUsIGhhc0NoYW5nZWQgfSBmcm9tIFwidmFseXJpYW4uanMvdXRpbHNcIjtcblxudHlwZSBTdGF0ZSA9IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbmV4cG9ydCB0eXBlIFB1bHNlQ29udGV4dCA9IHtcbiAgJGZsdXNoOiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xufTtcblxuZXhwb3J0IHR5cGUgUHVsc2U8U3RhdGVUeXBlLCBUUmV0dXJuID0gdW5rbm93bj4gPSAoXG4gIHRoaXM6IFB1bHNlQ29udGV4dCxcbiAgc3RhdGU6IFN0YXRlVHlwZSxcbiAgLi4uYXJnczogYW55W11cbikgPT4gVFJldHVybiB8IFByb21pc2U8VFJldHVybj47XG5cbmV4cG9ydCB0eXBlIFB1bHNlczxTdGF0ZVR5cGU+ID0gUmVjb3JkPHN0cmluZywgUHVsc2U8U3RhdGVUeXBlLCBhbnk+PjtcblxudHlwZSBQcm94eVN0YXRlPFN0YXRlVHlwZT4gPSBTdGF0ZVR5cGUgJiB7IFtrZXk6IHN0cmluZ106IGFueSB9O1xuXG5jb25zdCBlZmZlY3RTdGFjazogRnVuY3Rpb25bXSA9IFtdO1xuXG50eXBlIFN0b3JlUHVsc2VzPFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8YW55Pj4gPSB7XG4gIFtLIGluIGtleW9mIFB1bHNlc1R5cGVdOiBQdWxzZXNUeXBlW0tdIGV4dGVuZHMgKHRoaXM6IGFueSwgc3RhdGU6IGFueSwgLi4uYXJnczogaW5mZXIgQXJncykgPT4gaW5mZXIgUlxuICAgID8gKC4uLmFyZ3M6IEFyZ3MpID0+IFJcbiAgICA6IG5ldmVyO1xufTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJEb21TdWJzY3JpcHRpb24oc3Vic2NyaWJlcnM6IFNldDxGdW5jdGlvbj4sIGRvbVdpdGhWbm9kZXNUb1VwZGF0ZTogV2Vha1NldDxEb21FbGVtZW50Pik6IHZvaWQge1xuICBjb25zdCBjdXJyZW50Vm5vZGUgPSBjdXJyZW50LnZub2RlIGFzIFZub2RlV2l0aERvbTtcbiAgaWYgKCFjdXJyZW50Vm5vZGUgfHwgZG9tV2l0aFZub2Rlc1RvVXBkYXRlLmhhcyhjdXJyZW50Vm5vZGUuZG9tKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBoYXNQYXJlbnQgPSBmYWxzZTtcbiAgbGV0IHBhcmVudCA9IGN1cnJlbnRWbm9kZS5kb20ucGFyZW50RWxlbWVudCBhcyBEb21FbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKGRvbVdpdGhWbm9kZXNUb1VwZGF0ZS5oYXMocGFyZW50KSkge1xuICAgICAgaGFzUGFyZW50ID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50RWxlbWVudCBhcyBEb21FbGVtZW50O1xuICB9XG5cbiAgaWYgKCFoYXNQYXJlbnQpIHtcbiAgICBjb25zdCBkb20gPSBjdXJyZW50Vm5vZGUuZG9tO1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9ICgpID0+IHtcbiAgICAgIHVwZGF0ZVZub2RlKGRvbS52bm9kZSk7XG4gICAgICBpZiAoIWRvbS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgIHN1YnNjcmliZXJzLmRlbGV0ZShzdWJzY3JpcHRpb24pO1xuICAgICAgICBkb21XaXRoVm5vZGVzVG9VcGRhdGUuZGVsZXRlKGRvbSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBzdWJzY3JpYmVycy5hZGQoc3Vic2NyaXB0aW9uKTtcbiAgICBkb21XaXRoVm5vZGVzVG9VcGRhdGUuYWRkKGRvbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlU3RvcmU8U3RhdGVUeXBlIGV4dGVuZHMgU3RhdGUsIFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8U3RhdGVUeXBlPj4oXG4gIGluaXRpYWxTdGF0ZTogU3RhdGVUeXBlIHwgKCgpID0+IFN0YXRlVHlwZSkgfCBudWxsLFxuICBwdWxzZXM6IFB1bHNlc1R5cGUsXG4gIGltbXV0YWJsZSA9IGZhbHNlXG4pOiBTdG9yZVB1bHNlczxQdWxzZXNUeXBlPiAmIHtcbiAgc3RhdGU6IFByb3h5U3RhdGU8U3RhdGVUeXBlPjtcbiAgb246IChldmVudDogc3RyaW5nLCBjYWxsYmFjazogRnVuY3Rpb24pID0+IHZvaWQ7XG4gIG9mZjogKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4gdm9pZDtcbn0ge1xuICBjb25zdCBzdWJzY3JpYmVycyA9IG5ldyBTZXQ8RnVuY3Rpb24+KCk7XG4gIGNvbnN0IGRvbVdpdGhWbm9kZXNUb1VwZGF0ZSA9IG5ldyBXZWFrU2V0PERvbUVsZW1lbnQ+KCk7XG5cbiAgY29uc3QgYm91bmRQdWxzZXM6IFJlY29yZDxzdHJpbmcsIEZ1bmN0aW9uPiA9IHt9O1xuICBmb3IgKGNvbnN0IGtleSBpbiBwdWxzZXMpIHtcbiAgICBpZiAodHlwZW9mIHB1bHNlc1trZXldICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUHVsc2UgJyR7a2V5fScgbXVzdCBiZSBhIGZ1bmN0aW9uYCk7XG4gICAgfVxuICAgIGlmIChrZXkgPT09IFwic3RhdGVcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBIHB1bHNlIGNhbm5vdCBiZSBuYW1lZCAnc3RhdGUnYCk7XG4gICAgfVxuICAgIGJvdW5kUHVsc2VzW2tleV0gPSBnZXRQdWxzZU1ldGhvZChrZXkpO1xuICB9XG5cbiAgY29uc3QgbG9jYWxTdGF0ZTogU3RhdGVUeXBlID1cbiAgICAodHlwZW9mIGluaXRpYWxTdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gaW5pdGlhbFN0YXRlKCkgOiBpbml0aWFsU3RhdGUpIHx8ICh7fSBhcyBTdGF0ZVR5cGUpO1xuXG4gIGZ1bmN0aW9uIGlzTXV0YWJsZSgpIHtcbiAgICBpZiAoaW1tdXRhYmxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJZb3UgbmVlZCB0byBjYWxsIGEgcHVsc2UgdG8gbW9kaWZ5IHRoZSBzdGF0ZVwiKTtcbiAgICB9XG4gIH1cblxuICBsZXQgY3VycmVudFN0YXRlOiBTdGF0ZVR5cGUgfCBudWxsID0gbnVsbDtcbiAgbGV0IHB1bHNlQ2FsbENvdW50ID0gMDtcblxuICBjb25zdCBwcm94eVN0YXRlID0gbmV3IFByb3h5KGxvY2FsU3RhdGUsIHtcbiAgICBnZXQ6IChzdGF0ZSwgcHJvcDogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoY3VycmVudFN0YXRlKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50U3RhdGVbcHJvcF07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGN1cnJlbnRFZmZlY3QgPSBlZmZlY3RTdGFja1tlZmZlY3RTdGFjay5sZW5ndGggLSAxXTtcbiAgICAgIGlmIChjdXJyZW50RWZmZWN0ICYmICFzdWJzY3JpYmVycy5oYXMoY3VycmVudEVmZmVjdCkpIHtcbiAgICAgICAgc3Vic2NyaWJlcnMuYWRkKGN1cnJlbnRFZmZlY3QpO1xuICAgICAgfVxuXG4gICAgICByZWdpc3RlckRvbVN1YnNjcmlwdGlvbihzdWJzY3JpYmVycywgZG9tV2l0aFZub2Rlc1RvVXBkYXRlKTtcblxuICAgICAgcmV0dXJuIHN0YXRlW3Byb3BdO1xuICAgIH0sXG4gICAgc2V0OiAoc3RhdGUsIHByb3A6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgaXNNdXRhYmxlKCk7XG4gICAgICBSZWZsZWN0LnNldChzdGF0ZSwgcHJvcCwgdmFsdWUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICBkZWxldGVQcm9wZXJ0eTogKHN0YXRlLCBwcm9wOiBzdHJpbmcpID0+IHtcbiAgICAgIGlzTXV0YWJsZSgpO1xuICAgICAgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eShzdGF0ZSwgcHJvcCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIHN5bmNTdGF0ZShuZXdTdGF0ZTogU3RhdGVUeXBlKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gbmV3U3RhdGUpIHtcbiAgICAgIGxvY2FsU3RhdGVba2V5XSA9IGltbXV0YWJsZSA/IGRlZXBGcmVlemUobmV3U3RhdGVba2V5XSkgOiBuZXdTdGF0ZVtrZXldO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBsb2NhbFN0YXRlKSB7XG4gICAgICBpZiAoIShrZXkgaW4gbmV3U3RhdGUpKSB7XG4gICAgICAgIFJlZmxlY3QuZGVsZXRlUHJvcGVydHkobG9jYWxTdGF0ZSwga2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgZGVib3VuY2VUaW1lb3V0OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBmdW5jdGlvbiBkZWJvdW5jZWRVcGRhdGUoKSB7XG4gICAgaWYgKGRlYm91bmNlVGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KGRlYm91bmNlVGltZW91dCk7XG4gICAgfVxuICAgIGRlYm91bmNlVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gc3Vic2NyaWJlcnMuZm9yRWFjaCgoc3Vic2NyaWJlcikgPT4gc3Vic2NyaWJlcigpKSwgMCk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTdGF0ZShuZXdTdGF0ZTogU3RhdGVUeXBlLCBmbHVzaCA9IGZhbHNlKSB7XG4gICAgcHVsc2VDYWxsQ291bnQtLTtcbiAgICBpZiAoIWhhc0NoYW5nZWQobG9jYWxTdGF0ZSwgbmV3U3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwdWxzZUNhbGxDb3VudCA+IDAgJiYgIWZsdXNoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN5bmNTdGF0ZShuZXdTdGF0ZSk7XG4gICAgY3VycmVudFN0YXRlID0gbnVsbDtcbiAgICBkZWJvdW5jZWRVcGRhdGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFB1bHNlTWV0aG9kKGtleTogc3RyaW5nKSB7XG4gICAgZnVuY3Rpb24gcHVsc2VNZXRob2QodGhpczogUHVsc2VDb250ZXh0LCAuLi5hcmdzOiBhbnlbXSkge1xuICAgICAgcHVsc2VDYWxsQ291bnQrKztcbiAgICAgIGlmIChjdXJyZW50U3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgY3VycmVudFN0YXRlID0gZGVlcENsb25lVW5mcmVlemUobG9jYWxTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuJGZsdXNoID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoY3VycmVudFN0YXRlKSB7XG4gICAgICAgICAgc2V0U3RhdGUoY3VycmVudFN0YXRlLCB0cnVlKTtcbiAgICAgICAgICBjdXJyZW50U3RhdGUgPSBkZWVwQ2xvbmVVbmZyZWV6ZShsb2NhbFN0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAwKSk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBlbXB0eUZsdXNoID0gYXN5bmMgKCkgPT4ge307XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHB1bHNlUmVzdWx0ID0gcHVsc2VzW2tleV0uYXBwbHkodGhpcywgW2N1cnJlbnRTdGF0ZSwgLi4uYXJnc10pO1xuICAgICAgICBpZiAocHVsc2VSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgcmV0dXJuIHB1bHNlUmVzdWx0XG4gICAgICAgICAgICAudGhlbigocmVzb2x2ZWRWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICBzZXRTdGF0ZShjdXJyZW50U3RhdGUgYXMgU3RhdGVUeXBlKTtcbiAgICAgICAgICAgICAgdGhpcy4kZmx1c2ggPSBlbXB0eUZsdXNoO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRWYWx1ZTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGluIHB1bHNlICcke2tleX0nOmAsIGVycm9yKTtcbiAgICAgICAgICAgICAgdGhpcy4kZmx1c2ggPSBlbXB0eUZsdXNoO1xuICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldFN0YXRlKGN1cnJlbnRTdGF0ZSk7XG4gICAgICAgICAgdGhpcy4kZmx1c2ggPSBlbXB0eUZsdXNoO1xuICAgICAgICAgIHJldHVybiBwdWxzZVJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gcHVsc2UgJyR7a2V5fSc6YCwgZXJyb3IpO1xuICAgICAgICBSZWZsZWN0LnNldCh0aGlzLCBcIiRmbHVzaFwiLCBlbXB0eUZsdXNoKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHB1bHNlTWV0aG9kO1xuICB9XG5cbiAgc3luY1N0YXRlKGxvY2FsU3RhdGUpO1xuXG4gIGNvbnN0IGxpc3RlbmVyczogUmVjb3JkPHN0cmluZywgRnVuY3Rpb25bXT4gPSB7fTtcbiAgY29uc3QgdHJpZ2dlciA9IChldmVudDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIGlmIChsaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICBsaXN0ZW5lcnNbZXZlbnRdLmZvckVhY2goKGNhbGxiYWNrKSA9PiBjYWxsYmFjayguLi5hcmdzKSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHB1bHNlc1Byb3h5ID0gbmV3IFByb3h5KGJvdW5kUHVsc2VzLCB7XG4gICAgZ2V0OiAocHVsc2VzLCBwcm9wOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChwcm9wID09PSBcInN0YXRlXCIpIHtcbiAgICAgICAgcmV0dXJuIHByb3h5U3RhdGU7XG4gICAgICB9XG4gICAgICBpZiAocHJvcCA9PT0gXCJvblwiKSB7XG4gICAgICAgIHJldHVybiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uKSA9PiB7XG4gICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnNbZXZlbnRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIGxpc3RlbmVyc1tldmVudF0ucHVzaChjYWxsYmFjayk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBpZiAocHJvcCA9PT0gXCJvZmZcIikge1xuICAgICAgICByZXR1cm4gKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4ge1xuICAgICAgICAgIGlmIChsaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnNbZXZlbnRdID0gbGlzdGVuZXJzW2V2ZW50XS5maWx0ZXIoKGNiKSA9PiBjYiAhPT0gY2FsbGJhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmICghKHByb3AgaW4gcHVsc2VzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFB1bHNlICcke3Byb3B9JyBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgfVxuICAgICAgY29uc3QgcHVsc2VNZXRob2QgPSBwdWxzZXNbcHJvcF07XG5cbiAgICAgIHJldHVybiAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcHVsc2VNZXRob2QuYXBwbHkocHVsc2VNZXRob2QsIGFyZ3MpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocikgPT4ge1xuICAgICAgICAgICAgdHJpZ2dlcihcInB1bHNlXCIsIHByb3AsIGFyZ3MpO1xuICAgICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdHJpZ2dlcihcInB1bHNlXCIsIHByb3AsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwdWxzZXNQcm94eSBhcyBTdG9yZVB1bHNlczxQdWxzZXNUeXBlPiAmIHtcbiAgICBzdGF0ZTogUHJveHlTdGF0ZTxTdGF0ZVR5cGU+O1xuICAgIG9uOiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uKSA9PiB2b2lkO1xuICAgIG9mZjogKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4gdm9pZDtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVB1bHNlU3RvcmU8U3RhdGVUeXBlIGV4dGVuZHMgU3RhdGUsIFB1bHNlc1R5cGUgZXh0ZW5kcyBQdWxzZXM8U3RhdGVUeXBlPj4oXG4gIGluaXRpYWxTdGF0ZTogU3RhdGVUeXBlLFxuICBwdWxzZXM6IFB1bHNlc1R5cGVcbikge1xuICByZXR1cm4gY3JlYXRlU3RvcmUoaW5pdGlhbFN0YXRlLCBwdWxzZXMsIHRydWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTXV0YWJsZVN0b3JlPFN0YXRlVHlwZSBleHRlbmRzIFN0YXRlLCBQdWxzZXNUeXBlIGV4dGVuZHMgUHVsc2VzPFN0YXRlVHlwZT4+KFxuICBpbml0aWFsU3RhdGU6IFN0YXRlVHlwZSxcbiAgcHVsc2VzOiBQdWxzZXNUeXBlXG4pIHtcbiAgY29uc29sZS53YXJuKFxuICAgIFwiV2FybmluZzogWW91IGFyZSB3b3JraW5nIHdpdGggYSBtdXRhYmxlIHN0YXRlLiBBbGwgc3RhdGUgY2hhbmdlcyBtYWRlIG91dHNpZGUgb2YgYSBwdWxzZSB3aWxsIG5vdCB0cmlnZ2VyIGEgcmUtcmVuZGVyLlwiXG4gICk7XG4gIHJldHVybiBjcmVhdGVTdG9yZShpbml0aWFsU3RhdGUsIHB1bHNlcywgZmFsc2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWZmZWN0KGVmZmVjdDogRnVuY3Rpb24pIHtcbiAgY29uc3QgcnVuRWZmZWN0ID0gKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBlZmZlY3RTdGFjay5wdXNoKHJ1bkVmZmVjdCk7XG4gICAgICBlZmZlY3QoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZWZmZWN0U3RhY2sucG9wKCk7XG4gICAgfVxuICB9O1xuICBydW5FZmZlY3QoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVB1bHNlPFQ+KGluaXRpYWxWYWx1ZTogVCk6IFsoKSA9PiBULCAobmV3VmFsdWU6IFQgfCAoKGN1cnJlbnQ6IFQpID0+IFQpKSA9PiB2b2lkLCAoKSA9PiB2b2lkXSB7XG4gIGxldCB2YWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgY29uc3Qgc3Vic2NyaWJlcnMgPSBuZXcgU2V0PEZ1bmN0aW9uPigpO1xuICBjb25zdCBkb21XaXRoVm5vZGVzVG9VcGRhdGUgPSBuZXcgV2Vha1NldDxEb21FbGVtZW50PigpO1xuXG4gIGNvbnN0IHJ1blN1YnNjcmliZXJzID0gKCkgPT4ge1xuICAgIHN1YnNjcmliZXJzLmZvckVhY2goKHN1YnNjcmliZXIpID0+IHN1YnNjcmliZXIoKSk7XG4gIH07XG5cbiAgY29uc3QgcmVhZCA9ICgpOiBUID0+IHtcbiAgICBjb25zdCBjdXJyZW50RWZmZWN0ID0gZWZmZWN0U3RhY2tbZWZmZWN0U3RhY2subGVuZ3RoIC0gMV07XG4gICAgaWYgKGN1cnJlbnRFZmZlY3QgJiYgIXN1YnNjcmliZXJzLmhhcyhjdXJyZW50RWZmZWN0KSkge1xuICAgICAgc3Vic2NyaWJlcnMuYWRkKGN1cnJlbnRFZmZlY3QpO1xuICAgIH1cbiAgICByZWdpc3RlckRvbVN1YnNjcmlwdGlvbihzdWJzY3JpYmVycywgZG9tV2l0aFZub2Rlc1RvVXBkYXRlKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgY29uc3Qgd3JpdGUgPSAobmV3VmFsdWU6IFQgfCAoKGN1cnJlbnQ6IFQpID0+IFQpKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVzb2x2ZWRWYWx1ZSA9IHR5cGVvZiBuZXdWYWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gKG5ld1ZhbHVlIGFzIChjdXJyZW50OiBUKSA9PiBUKSh2YWx1ZSkgOiBuZXdWYWx1ZTtcbiAgICBpZiAoIWhhc0NoYW5nZWQodmFsdWUsIHJlc29sdmVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhbHVlID0gcmVzb2x2ZWRWYWx1ZTtcbiAgICBydW5TdWJzY3JpYmVycygpO1xuICB9O1xuXG4gIHJldHVybiBbcmVhZCwgd3JpdGUsIHJ1blN1YnNjcmliZXJzXTtcbn1cbiJdLCJtYXBwaW5ncyI6ImdKQUFBQSxFQUFBLEcseURBQUFDLENBQUFELEVBQUEsQ0FBQUUsYUFBQSxJQUFBQSxFQUFBQyxtQkFBQSxJQUFBQSxFQUFBQyxZQUFBLElBQUFBLEVBQUFDLGlCQUFBLElBQUFBLElBQUEsSSxFQUFBQyxHLEVBQUFOLEUsME1BQ0FPLEVBQStEQyxRQUFBLGVBQy9EQyxFQUEwREQsUUFBQSxxQkFrQnBERSxFQUEwQixHQVFoQyxTQUFTQyxFQUF3QkMsRUFBNEJDLEdBQzNELE1BQU1DLEVBQWVQLEVBQUFRLFFBQVFDLE1BQzdCLElBQUtGLEdBQWdCRCxFQUFzQkksSUFBSUgsRUFBYUksS0FDMUQsT0FHRixJQUFJQyxHQUFZLEVBQ1pDLEVBQVNOLEVBQWFJLElBQUlHLGNBQzlCLEtBQU9ELEdBQVEsQ0FDYixHQUFJUCxFQUFzQkksSUFBSUcs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
|
package/dist/pulses/index.mjs
CHANGED
|
@@ -108,12 +108,13 @@ function createStore(initialState, pulses, immutable = false) {
|
|
|
108
108
|
if (currentState === null) {
|
|
109
109
|
currentState = deepCloneUnfreeze(localState);
|
|
110
110
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
this.$flush = async () => {
|
|
112
|
+
if (currentState) {
|
|
113
|
+
setState(currentState, true);
|
|
114
|
+
currentState = deepCloneUnfreeze(localState);
|
|
115
|
+
}
|
|
114
116
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
115
117
|
};
|
|
116
|
-
Reflect.set(this, "$flush", $flush);
|
|
117
118
|
const emptyFlush = async () => {
|
|
118
119
|
};
|
|
119
120
|
try {
|
|
@@ -121,16 +122,16 @@ function createStore(initialState, pulses, immutable = false) {
|
|
|
121
122
|
if (pulseResult instanceof Promise) {
|
|
122
123
|
return pulseResult.then((resolvedValue) => {
|
|
123
124
|
setState(currentState);
|
|
124
|
-
|
|
125
|
+
this.$flush = emptyFlush;
|
|
125
126
|
return resolvedValue;
|
|
126
127
|
}).catch((error) => {
|
|
127
128
|
console.error(`Error in pulse '${key}':`, error);
|
|
128
|
-
|
|
129
|
+
this.$flush = emptyFlush;
|
|
129
130
|
throw error;
|
|
130
131
|
});
|
|
131
132
|
} else {
|
|
132
133
|
setState(currentState);
|
|
133
|
-
|
|
134
|
+
this.$flush = emptyFlush;
|
|
134
135
|
return pulseResult;
|
|
135
136
|
}
|
|
136
137
|
} catch (error) {
|
|
@@ -172,20 +173,17 @@ function createStore(initialState, pulses, immutable = false) {
|
|
|
172
173
|
throw new Error(`Pulse '${prop}' does not exist`);
|
|
173
174
|
}
|
|
174
175
|
const pulseMethod = pulses2[prop];
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
return pulseMethod;
|
|
176
|
+
return (...args) => {
|
|
177
|
+
const result = pulseMethod.apply(pulseMethod, args);
|
|
178
|
+
if (result instanceof Promise) {
|
|
179
|
+
return result.then((r) => {
|
|
180
|
+
trigger("pulse", prop, args);
|
|
181
|
+
return r;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
trigger("pulse", prop, args);
|
|
185
|
+
return result;
|
|
186
|
+
};
|
|
189
187
|
}
|
|
190
188
|
});
|
|
191
189
|
return pulsesProxy;
|
|
@@ -195,7 +193,7 @@ function createPulseStore(initialState, pulses) {
|
|
|
195
193
|
}
|
|
196
194
|
function createMutableStore(initialState, pulses) {
|
|
197
195
|
console.warn(
|
|
198
|
-
"Warning: You are working with a mutable state.
|
|
196
|
+
"Warning: You are working with a mutable state. All state changes made outside of a pulse will not trigger a re-render."
|
|
199
197
|
);
|
|
200
198
|
return createStore(initialState, pulses, false);
|
|
201
199
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../lib/pulses/index.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-console */\nimport { updateVnode, VnodeWithDom, current, DomElement } from \"valyrian.js\";\nimport { deepCloneUnfreeze, deepFreeze, hasChanged } from \"valyrian.js/utils\";\n\ntype State = Record<string, any>;\n\nexport type Pulse<StateType, TReturn = unknown> = (state: StateType, ...args: any[]) => TReturn | Promise<TReturn>;\n\nexport type Pulses<StateType> = Record<string, Pulse<StateType, any> & { $flush?: () => Promise<void> }>;\n\ntype ProxyState<StateType> = StateType & { [key: string]: any };\n\nconst effectStack: Function[] = [];\n\ntype StorePulses<PulsesType extends Pulses<any>> = {\n [K in keyof PulsesType]: PulsesType[K] extends (state: any, ...args: infer Args) => infer R\n ? (...args: Args) => R\n : never;\n};\n\n/** Funci\u00F3n auxiliar para registrar la suscripci\u00F3n al nodo DOM.\n * Retorna true si se agreg\u00F3 la suscripci\u00F3n, o false si se encontr\u00F3 un nodo padre ya suscrito.\n */\nfunction registerDomSubscription(subscribers: Set<Function>, domWithVnodesToUpdate: WeakSet<DomElement>): void {\n const currentVnode = current.vnode as VnodeWithDom;\n if (!currentVnode || domWithVnodesToUpdate.has(currentVnode.dom)) {\n return;\n }\n\n let hasParent = false;\n let parent = currentVnode.dom.parentElement as DomElement;\n while (parent) {\n if (domWithVnodesToUpdate.has(parent)) {\n hasParent = true;\n break;\n }\n parent = parent.parentElement as DomElement;\n }\n\n // Si no hay nodo padre registrado, se crea la suscripci\u00F3n.\n if (!hasParent) {\n const dom = currentVnode.dom;\n const subscription = () => {\n updateVnode(dom.vnode);\n if (!dom.parentElement) {\n subscribers.delete(subscription);\n domWithVnodesToUpdate.delete(dom);\n }\n };\n subscribers.add(subscription);\n domWithVnodesToUpdate.add(dom);\n }\n}\n\nfunction createStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType | (() => StateType) | null,\n pulses: PulsesType,\n immutable = false\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const boundPulses: Pulses<StateType> = {};\n for (const key in pulses) {\n if (typeof pulses[key] !== \"function\") {\n throw new Error(`Pulse '${key}' must be a function`);\n }\n if (key === \"state\") {\n throw new Error(`A pulse cannot be named 'state'`);\n }\n boundPulses[key] = getPulseMethod(key);\n }\n\n const localState: StateType =\n (typeof initialState === \"function\" ? initialState() : initialState) || ({} as StateType);\n\n function isMutable() {\n if (immutable) {\n throw new Error(\"You need to call a pulse to modify the state\");\n }\n }\n\n let currentState: StateType | null = null;\n let pulseCallCount = 0;\n\n const proxyState = new Proxy(localState, {\n get: (state, prop: string) => {\n // If we are in a pulse, we return the value of the cloned state.\n if (currentState) {\n return currentState[prop];\n }\n\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n\n return state[prop];\n },\n set: (state, prop: string, value: any) => {\n isMutable();\n Reflect.set(state, prop, value);\n return true;\n },\n deleteProperty: (state, prop: string) => {\n isMutable();\n Reflect.deleteProperty(state, prop);\n return true;\n }\n });\n\n function syncState(newState: StateType) {\n for (const key in newState) {\n localState[key] = immutable ? deepFreeze(newState[key]) : newState[key];\n }\n for (const key in localState) {\n if (!(key in newState)) {\n Reflect.deleteProperty(localState, key);\n }\n }\n }\n\n let debounceTimeout: ReturnType<typeof setTimeout> | null = null;\n function debouncedUpdate() {\n if (debounceTimeout) {\n clearTimeout(debounceTimeout);\n }\n debounceTimeout = setTimeout(() => subscribers.forEach((subscriber) => subscriber()), 0);\n }\n\n function setState(newState: StateType, flush = false) {\n pulseCallCount--;\n if (!hasChanged(localState, newState)) {\n return;\n }\n if (pulseCallCount > 0 && !flush) {\n return;\n }\n syncState(newState);\n currentState = null;\n debouncedUpdate();\n }\n\n function getPulseMethod(key: string) {\n function pulseMethod(this: Pulse<StateType, any> & { $flush: () => Promise<void> }, ...args: any[]) {\n pulseCallCount++;\n if (currentState === null) {\n currentState = deepCloneUnfreeze(localState);\n }\n\n const $flush = async () => {\n setState(currentState as StateType, true);\n currentState = deepCloneUnfreeze(localState);\n await new Promise((resolve) => setTimeout(resolve, 0));\n };\n\n Reflect.set(this, \"$flush\", $flush);\n const emptyFlush = async () => {};\n\n try {\n const pulseResult = pulses[key].apply(this, [currentState, ...args] as any);\n if (pulseResult instanceof Promise) {\n return pulseResult\n .then((resolvedValue) => {\n setState(currentState as StateType);\n Reflect.set(this, \"$flush\", emptyFlush);\n return resolvedValue;\n })\n .catch((error) => {\n console.error(`Error in pulse '${key}':`, error);\n Reflect.set(this, \"$flush\", emptyFlush);\n throw error;\n });\n } else {\n setState(currentState);\n Reflect.set(this, \"$flush\", emptyFlush);\n return pulseResult;\n }\n } catch (error) {\n console.error(`Error in pulse '${key}':`, error);\n Reflect.set(this, \"$flush\", emptyFlush);\n throw error;\n }\n }\n\n return pulseMethod;\n }\n\n syncState(localState);\n\n const listeners: Record<string, Function[]> = {};\n const trigger = (event: string, ...args: any[]) => {\n if (listeners[event]) {\n listeners[event].forEach((callback) => callback(...args));\n }\n };\n\n const pulsesProxy = new Proxy(boundPulses, {\n get: (pulses, prop: string) => {\n if (prop === \"state\") {\n return proxyState;\n }\n if (prop === \"on\") {\n return (event: string, callback: Function) => {\n if (!listeners[event]) {\n listeners[event] = [];\n }\n listeners[event].push(callback);\n };\n }\n if (prop === \"off\") {\n return (event: string, callback: Function) => {\n if (listeners[event]) {\n listeners[event] = listeners[event].filter((cb) => cb !== callback);\n }\n };\n }\n if (!(prop in pulses)) {\n throw new Error(`Pulse '${prop}' does not exist`);\n }\n const pulseMethod = pulses[prop];\n\n if (typeof pulseMethod === \"function\") {\n return (...args: any[]) => {\n const result = pulseMethod.apply(pulsesProxy, args as any);\n if (result instanceof Promise) {\n return result.then((r) => {\n trigger(\"pulse\", prop, args);\n return r;\n });\n }\n trigger(\"pulse\", prop, args);\n return result;\n };\n }\n\n return pulseMethod;\n }\n });\n\n return pulsesProxy as StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n };\n}\n\nexport function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n return createStore(initialState, pulses, true);\n}\n\nexport function createMutableStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n console.warn(\n \"Warning: You are working with a mutable state. This can lead to unpredictable behavior. All state changes made outside of a pulse will not trigger a re-render.\"\n );\n return createStore(initialState, pulses, false);\n}\n\nexport function createEffect(effect: Function) {\n const runEffect = () => {\n try {\n effectStack.push(runEffect);\n effect();\n } finally {\n effectStack.pop();\n }\n };\n runEffect();\n}\n\nexport function createPulse<T>(initialValue: T): [() => T, (newValue: T | ((current: T) => T)) => void, () => void] {\n let value = initialValue;\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const runSubscribers = () => {\n subscribers.forEach((subscriber) => subscriber());\n };\n\n const read = (): T => {\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n return value;\n };\n\n const write = (newValue: T | ((current: T) => T)): void => {\n const resolvedValue = typeof newValue === \"function\" ? (newValue as (current: T) => T)(value) : newValue;\n if (!hasChanged(value, resolvedValue)) {\n return;\n }\n value = resolvedValue;\n runSubscribers();\n };\n\n return [read, write, runSubscribers];\n}\n"],
|
|
5
|
-
"mappings": ";AACA,SAAS,aAA2B,eAA2B;AAC/D,SAAS,mBAAmB,YAAY,kBAAkB;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-console */\nimport { updateVnode, VnodeWithDom, current, DomElement } from \"valyrian.js\";\nimport { deepCloneUnfreeze, deepFreeze, hasChanged } from \"valyrian.js/utils\";\n\ntype State = Record<string, any>;\n\nexport type PulseContext = {\n $flush: () => Promise<void>;\n};\n\nexport type Pulse<StateType, TReturn = unknown> = (\n this: PulseContext,\n state: StateType,\n ...args: any[]\n) => TReturn | Promise<TReturn>;\n\nexport type Pulses<StateType> = Record<string, Pulse<StateType, any>>;\n\ntype ProxyState<StateType> = StateType & { [key: string]: any };\n\nconst effectStack: Function[] = [];\n\ntype StorePulses<PulsesType extends Pulses<any>> = {\n [K in keyof PulsesType]: PulsesType[K] extends (this: any, state: any, ...args: infer Args) => infer R\n ? (...args: Args) => R\n : never;\n};\n\nfunction registerDomSubscription(subscribers: Set<Function>, domWithVnodesToUpdate: WeakSet<DomElement>): void {\n const currentVnode = current.vnode as VnodeWithDom;\n if (!currentVnode || domWithVnodesToUpdate.has(currentVnode.dom)) {\n return;\n }\n\n let hasParent = false;\n let parent = currentVnode.dom.parentElement as DomElement;\n while (parent) {\n if (domWithVnodesToUpdate.has(parent)) {\n hasParent = true;\n break;\n }\n parent = parent.parentElement as DomElement;\n }\n\n if (!hasParent) {\n const dom = currentVnode.dom;\n const subscription = () => {\n updateVnode(dom.vnode);\n if (!dom.parentElement) {\n subscribers.delete(subscription);\n domWithVnodesToUpdate.delete(dom);\n }\n };\n subscribers.add(subscription);\n domWithVnodesToUpdate.add(dom);\n }\n}\n\nfunction createStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType | (() => StateType) | null,\n pulses: PulsesType,\n immutable = false\n): StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n} {\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const boundPulses: Record<string, Function> = {};\n for (const key in pulses) {\n if (typeof pulses[key] !== \"function\") {\n throw new Error(`Pulse '${key}' must be a function`);\n }\n if (key === \"state\") {\n throw new Error(`A pulse cannot be named 'state'`);\n }\n boundPulses[key] = getPulseMethod(key);\n }\n\n const localState: StateType =\n (typeof initialState === \"function\" ? initialState() : initialState) || ({} as StateType);\n\n function isMutable() {\n if (immutable) {\n throw new Error(\"You need to call a pulse to modify the state\");\n }\n }\n\n let currentState: StateType | null = null;\n let pulseCallCount = 0;\n\n const proxyState = new Proxy(localState, {\n get: (state, prop: string) => {\n if (currentState) {\n return currentState[prop];\n }\n\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n\n return state[prop];\n },\n set: (state, prop: string, value: any) => {\n isMutable();\n Reflect.set(state, prop, value);\n return true;\n },\n deleteProperty: (state, prop: string) => {\n isMutable();\n Reflect.deleteProperty(state, prop);\n return true;\n }\n });\n\n function syncState(newState: StateType) {\n for (const key in newState) {\n localState[key] = immutable ? deepFreeze(newState[key]) : newState[key];\n }\n for (const key in localState) {\n if (!(key in newState)) {\n Reflect.deleteProperty(localState, key);\n }\n }\n }\n\n let debounceTimeout: ReturnType<typeof setTimeout> | null = null;\n function debouncedUpdate() {\n if (debounceTimeout) {\n clearTimeout(debounceTimeout);\n }\n debounceTimeout = setTimeout(() => subscribers.forEach((subscriber) => subscriber()), 0);\n }\n\n function setState(newState: StateType, flush = false) {\n pulseCallCount--;\n if (!hasChanged(localState, newState)) {\n return;\n }\n if (pulseCallCount > 0 && !flush) {\n return;\n }\n syncState(newState);\n currentState = null;\n debouncedUpdate();\n }\n\n function getPulseMethod(key: string) {\n function pulseMethod(this: PulseContext, ...args: any[]) {\n pulseCallCount++;\n if (currentState === null) {\n currentState = deepCloneUnfreeze(localState);\n }\n\n this.$flush = async () => {\n if (currentState) {\n setState(currentState, true);\n currentState = deepCloneUnfreeze(localState);\n }\n await new Promise((resolve) => setTimeout(resolve, 0));\n };\n\n const emptyFlush = async () => {};\n\n try {\n const pulseResult = pulses[key].apply(this, [currentState, ...args]);\n if (pulseResult instanceof Promise) {\n return pulseResult\n .then((resolvedValue) => {\n setState(currentState as StateType);\n this.$flush = emptyFlush;\n return resolvedValue;\n })\n .catch((error) => {\n console.error(`Error in pulse '${key}':`, error);\n this.$flush = emptyFlush;\n throw error;\n });\n } else {\n setState(currentState);\n this.$flush = emptyFlush;\n return pulseResult;\n }\n } catch (error) {\n console.error(`Error in pulse '${key}':`, error);\n Reflect.set(this, \"$flush\", emptyFlush);\n throw error;\n }\n }\n\n return pulseMethod;\n }\n\n syncState(localState);\n\n const listeners: Record<string, Function[]> = {};\n const trigger = (event: string, ...args: any[]) => {\n if (listeners[event]) {\n listeners[event].forEach((callback) => callback(...args));\n }\n };\n\n const pulsesProxy = new Proxy(boundPulses, {\n get: (pulses, prop: string) => {\n if (prop === \"state\") {\n return proxyState;\n }\n if (prop === \"on\") {\n return (event: string, callback: Function) => {\n if (!listeners[event]) {\n listeners[event] = [];\n }\n listeners[event].push(callback);\n };\n }\n if (prop === \"off\") {\n return (event: string, callback: Function) => {\n if (listeners[event]) {\n listeners[event] = listeners[event].filter((cb) => cb !== callback);\n }\n };\n }\n if (!(prop in pulses)) {\n throw new Error(`Pulse '${prop}' does not exist`);\n }\n const pulseMethod = pulses[prop];\n\n return (...args: any[]) => {\n const result = pulseMethod.apply(pulseMethod, args);\n if (result instanceof Promise) {\n return result.then((r) => {\n trigger(\"pulse\", prop, args);\n return r;\n });\n }\n trigger(\"pulse\", prop, args);\n return result;\n };\n }\n });\n\n return pulsesProxy as StorePulses<PulsesType> & {\n state: ProxyState<StateType>;\n on: (event: string, callback: Function) => void;\n off: (event: string, callback: Function) => void;\n };\n}\n\nexport function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n) {\n return createStore(initialState, pulses, true);\n}\n\nexport function createMutableStore<StateType extends State, PulsesType extends Pulses<StateType>>(\n initialState: StateType,\n pulses: PulsesType\n) {\n console.warn(\n \"Warning: You are working with a mutable state. All state changes made outside of a pulse will not trigger a re-render.\"\n );\n return createStore(initialState, pulses, false);\n}\n\nexport function createEffect(effect: Function) {\n const runEffect = () => {\n try {\n effectStack.push(runEffect);\n effect();\n } finally {\n effectStack.pop();\n }\n };\n runEffect();\n}\n\nexport function createPulse<T>(initialValue: T): [() => T, (newValue: T | ((current: T) => T)) => void, () => void] {\n let value = initialValue;\n const subscribers = new Set<Function>();\n const domWithVnodesToUpdate = new WeakSet<DomElement>();\n\n const runSubscribers = () => {\n subscribers.forEach((subscriber) => subscriber());\n };\n\n const read = (): T => {\n const currentEffect = effectStack[effectStack.length - 1];\n if (currentEffect && !subscribers.has(currentEffect)) {\n subscribers.add(currentEffect);\n }\n registerDomSubscription(subscribers, domWithVnodesToUpdate);\n return value;\n };\n\n const write = (newValue: T | ((current: T) => T)): void => {\n const resolvedValue = typeof newValue === \"function\" ? (newValue as (current: T) => T)(value) : newValue;\n if (!hasChanged(value, resolvedValue)) {\n return;\n }\n value = resolvedValue;\n runSubscribers();\n };\n\n return [read, write, runSubscribers];\n}\n"],
|
|
5
|
+
"mappings": ";AACA,SAAS,aAA2B,eAA2B;AAC/D,SAAS,mBAAmB,YAAY,kBAAkB;AAkB1D,IAAM,cAA0B,CAAC;AAQjC,SAAS,wBAAwB,aAA4B,uBAAkD;AAC7G,QAAM,eAAe,QAAQ;AAC7B,MAAI,CAAC,gBAAgB,sBAAsB,IAAI,aAAa,GAAG,GAAG;AAChE;AAAA,EACF;AAEA,MAAI,YAAY;AAChB,MAAI,SAAS,aAAa,IAAI;AAC9B,SAAO,QAAQ;AACb,QAAI,sBAAsB,IAAI,MAAM,GAAG;AACrC,kBAAY;AACZ;AAAA,IACF;AACA,aAAS,OAAO;AAAA,EAClB;AAEA,MAAI,CAAC,WAAW;AACd,UAAM,MAAM,aAAa;AACzB,UAAM,eAAe,MAAM;AACzB,kBAAY,IAAI,KAAK;AACrB,UAAI,CAAC,IAAI,eAAe;AACtB,oBAAY,OAAO,YAAY;AAC/B,8BAAsB,OAAO,GAAG;AAAA,MAClC;AAAA,IACF;AACA,gBAAY,IAAI,YAAY;AAC5B,0BAAsB,IAAI,GAAG;AAAA,EAC/B;AACF;AAEA,SAAS,YACP,cACA,QACA,YAAY,OAKZ;AACA,QAAM,cAAc,oBAAI,IAAc;AACtC,QAAM,wBAAwB,oBAAI,QAAoB;AAEtD,QAAM,cAAwC,CAAC;AAC/C,aAAW,OAAO,QAAQ;AACxB,QAAI,OAAO,OAAO,GAAG,MAAM,YAAY;AACrC,YAAM,IAAI,MAAM,UAAU,GAAG,sBAAsB;AAAA,IACrD;AACA,QAAI,QAAQ,SAAS;AACnB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,gBAAY,GAAG,IAAI,eAAe,GAAG;AAAA,EACvC;AAEA,QAAM,cACH,OAAO,iBAAiB,aAAa,aAAa,IAAI,iBAAkB,CAAC;AAE5E,WAAS,YAAY;AACnB,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AAAA,EACF;AAEA,MAAI,eAAiC;AACrC,MAAI,iBAAiB;AAErB,QAAM,aAAa,IAAI,MAAM,YAAY;AAAA,IACvC,KAAK,CAAC,OAAO,SAAiB;AAC5B,UAAI,cAAc;AAChB,eAAO,aAAa,IAAI;AAAA,MAC1B;AAEA,YAAM,gBAAgB,YAAY,YAAY,SAAS,CAAC;AACxD,UAAI,iBAAiB,CAAC,YAAY,IAAI,aAAa,GAAG;AACpD,oBAAY,IAAI,aAAa;AAAA,MAC/B;AAEA,8BAAwB,aAAa,qBAAqB;AAE1D,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA,IACA,KAAK,CAAC,OAAO,MAAc,UAAe;AACxC,gBAAU;AACV,cAAQ,IAAI,OAAO,MAAM,KAAK;AAC9B,aAAO;AAAA,IACT;AAAA,IACA,gBAAgB,CAAC,OAAO,SAAiB;AACvC,gBAAU;AACV,cAAQ,eAAe,OAAO,IAAI;AAClC,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,WAAS,UAAU,UAAqB;AACtC,eAAW,OAAO,UAAU;AAC1B,iBAAW,GAAG,IAAI,YAAY,WAAW,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG;AAAA,IACxE;AACA,eAAW,OAAO,YAAY;AAC5B,UAAI,EAAE,OAAO,WAAW;AACtB,gBAAQ,eAAe,YAAY,GAAG;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,kBAAwD;AAC5D,WAAS,kBAAkB;AACzB,QAAI,iBAAiB;AACnB,mBAAa,eAAe;AAAA,IAC9B;AACA,sBAAkB,WAAW,MAAM,YAAY,QAAQ,CAAC,eAAe,WAAW,CAAC,GAAG,CAAC;AAAA,EACzF;AAEA,WAAS,SAAS,UAAqB,QAAQ,OAAO;AACpD;AACA,QAAI,CAAC,WAAW,YAAY,QAAQ,GAAG;AACrC;AAAA,IACF;AACA,QAAI,iBAAiB,KAAK,CAAC,OAAO;AAChC;AAAA,IACF;AACA,cAAU,QAAQ;AAClB,mBAAe;AACf,oBAAgB;AAAA,EAClB;AAEA,WAAS,eAAe,KAAa;AACnC,aAAS,eAAmC,MAAa;AACvD;AACA,UAAI,iBAAiB,MAAM;AACzB,uBAAe,kBAAkB,UAAU;AAAA,MAC7C;AAEA,WAAK,SAAS,YAAY;AACxB,YAAI,cAAc;AAChB,mBAAS,cAAc,IAAI;AAC3B,yBAAe,kBAAkB,UAAU;AAAA,QAC7C;AACA,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA,MACvD;AAEA,YAAM,aAAa,YAAY;AAAA,MAAC;AAEhC,UAAI;AACF,cAAM,cAAc,OAAO,GAAG,EAAE,MAAM,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;AACnE,YAAI,uBAAuB,SAAS;AAClC,iBAAO,YACJ,KAAK,CAAC,kBAAkB;AACvB,qBAAS,YAAyB;AAClC,iBAAK,SAAS;AACd,mBAAO;AAAA,UACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,oBAAQ,MAAM,mBAAmB,GAAG,MAAM,KAAK;AAC/C,iBAAK,SAAS;AACd,kBAAM;AAAA,UACR,CAAC;AAAA,QACL,OAAO;AACL,mBAAS,YAAY;AACrB,eAAK,SAAS;AACd,iBAAO;AAAA,QACT;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,mBAAmB,GAAG,MAAM,KAAK;AAC/C,gBAAQ,IAAI,MAAM,UAAU,UAAU;AACtC,cAAM;AAAA,MACR;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,YAAU,UAAU;AAEpB,QAAM,YAAwC,CAAC;AAC/C,QAAM,UAAU,CAAC,UAAkB,SAAgB;AACjD,QAAI,UAAU,KAAK,GAAG;AACpB,gBAAU,KAAK,EAAE,QAAQ,CAAC,aAAa,SAAS,GAAG,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,cAAc,IAAI,MAAM,aAAa;AAAA,IACzC,KAAK,CAACA,SAAQ,SAAiB;AAC7B,UAAI,SAAS,SAAS;AACpB,eAAO;AAAA,MACT;AACA,UAAI,SAAS,MAAM;AACjB,eAAO,CAAC,OAAe,aAAuB;AAC5C,cAAI,CAAC,UAAU,KAAK,GAAG;AACrB,sBAAU,KAAK,IAAI,CAAC;AAAA,UACtB;AACA,oBAAU,KAAK,EAAE,KAAK,QAAQ;AAAA,QAChC;AAAA,MACF;AACA,UAAI,SAAS,OAAO;AAClB,eAAO,CAAC,OAAe,aAAuB;AAC5C,cAAI,UAAU,KAAK,GAAG;AACpB,sBAAU,KAAK,IAAI,UAAU,KAAK,EAAE,OAAO,CAAC,OAAO,OAAO,QAAQ;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AACA,UAAI,EAAE,QAAQA,UAAS;AACrB,cAAM,IAAI,MAAM,UAAU,IAAI,kBAAkB;AAAA,MAClD;AACA,YAAM,cAAcA,QAAO,IAAI;AAE/B,aAAO,IAAI,SAAgB;AACzB,cAAM,SAAS,YAAY,MAAM,aAAa,IAAI;AAClD,YAAI,kBAAkB,SAAS;AAC7B,iBAAO,OAAO,KAAK,CAAC,MAAM;AACxB,oBAAQ,SAAS,MAAM,IAAI;AAC3B,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,gBAAQ,SAAS,MAAM,IAAI;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAKT;AAEO,SAAS,iBACd,cACA,QACA;AACA,SAAO,YAAY,cAAc,QAAQ,IAAI;AAC/C;AAEO,SAAS,mBACd,cACA,QACA;AACA,UAAQ;AAAA,IACN;AAAA,EACF;AACA,SAAO,YAAY,cAAc,QAAQ,KAAK;AAChD;AAEO,SAAS,aAAa,QAAkB;AAC7C,QAAM,YAAY,MAAM;AACtB,QAAI;AACF,kBAAY,KAAK,SAAS;AAC1B,aAAO;AAAA,IACT,UAAE;AACA,kBAAY,IAAI;AAAA,IAClB;AAAA,EACF;AACA,YAAU;AACZ;AAEO,SAAS,YAAe,cAAqF;AAClH,MAAI,QAAQ;AACZ,QAAM,cAAc,oBAAI,IAAc;AACtC,QAAM,wBAAwB,oBAAI,QAAoB;AAEtD,QAAM,iBAAiB,MAAM;AAC3B,gBAAY,QAAQ,CAAC,eAAe,WAAW,CAAC;AAAA,EAClD;AAEA,QAAM,OAAO,MAAS;AACpB,UAAM,gBAAgB,YAAY,YAAY,SAAS,CAAC;AACxD,QAAI,iBAAiB,CAAC,YAAY,IAAI,aAAa,GAAG;AACpD,kBAAY,IAAI,aAAa;AAAA,IAC/B;AACA,4BAAwB,aAAa,qBAAqB;AAC1D,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,aAA4C;AACzD,UAAM,gBAAgB,OAAO,aAAa,aAAc,SAA+B,KAAK,IAAI;AAChG,QAAI,CAAC,WAAW,OAAO,aAAa,GAAG;AACrC;AAAA,IACF;AACA,YAAQ;AACR,mBAAe;AAAA,EACjB;AAEA,SAAO,CAAC,MAAM,OAAO,cAAc;AACrC;",
|
|
6
6
|
"names": ["pulses"]
|
|
7
7
|
}
|
package/lib/pulses/index.ts
CHANGED
|
@@ -4,23 +4,28 @@ import { deepCloneUnfreeze, deepFreeze, hasChanged } from "valyrian.js/utils";
|
|
|
4
4
|
|
|
5
5
|
type State = Record<string, any>;
|
|
6
6
|
|
|
7
|
-
export type
|
|
7
|
+
export type PulseContext = {
|
|
8
|
+
$flush: () => Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type Pulse<StateType, TReturn = unknown> = (
|
|
12
|
+
this: PulseContext,
|
|
13
|
+
state: StateType,
|
|
14
|
+
...args: any[]
|
|
15
|
+
) => TReturn | Promise<TReturn>;
|
|
8
16
|
|
|
9
|
-
export type Pulses<StateType> = Record<string, Pulse<StateType, any
|
|
17
|
+
export type Pulses<StateType> = Record<string, Pulse<StateType, any>>;
|
|
10
18
|
|
|
11
19
|
type ProxyState<StateType> = StateType & { [key: string]: any };
|
|
12
20
|
|
|
13
21
|
const effectStack: Function[] = [];
|
|
14
22
|
|
|
15
23
|
type StorePulses<PulsesType extends Pulses<any>> = {
|
|
16
|
-
[K in keyof PulsesType]: PulsesType[K] extends (state: any, ...args: infer Args) => infer R
|
|
24
|
+
[K in keyof PulsesType]: PulsesType[K] extends (this: any, state: any, ...args: infer Args) => infer R
|
|
17
25
|
? (...args: Args) => R
|
|
18
26
|
: never;
|
|
19
27
|
};
|
|
20
28
|
|
|
21
|
-
/** Función auxiliar para registrar la suscripción al nodo DOM.
|
|
22
|
-
* Retorna true si se agregó la suscripción, o false si se encontró un nodo padre ya suscrito.
|
|
23
|
-
*/
|
|
24
29
|
function registerDomSubscription(subscribers: Set<Function>, domWithVnodesToUpdate: WeakSet<DomElement>): void {
|
|
25
30
|
const currentVnode = current.vnode as VnodeWithDom;
|
|
26
31
|
if (!currentVnode || domWithVnodesToUpdate.has(currentVnode.dom)) {
|
|
@@ -37,7 +42,6 @@ function registerDomSubscription(subscribers: Set<Function>, domWithVnodesToUpda
|
|
|
37
42
|
parent = parent.parentElement as DomElement;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
// Si no hay nodo padre registrado, se crea la suscripción.
|
|
41
45
|
if (!hasParent) {
|
|
42
46
|
const dom = currentVnode.dom;
|
|
43
47
|
const subscription = () => {
|
|
@@ -64,7 +68,7 @@ function createStore<StateType extends State, PulsesType extends Pulses<StateTyp
|
|
|
64
68
|
const subscribers = new Set<Function>();
|
|
65
69
|
const domWithVnodesToUpdate = new WeakSet<DomElement>();
|
|
66
70
|
|
|
67
|
-
const boundPulses:
|
|
71
|
+
const boundPulses: Record<string, Function> = {};
|
|
68
72
|
for (const key in pulses) {
|
|
69
73
|
if (typeof pulses[key] !== "function") {
|
|
70
74
|
throw new Error(`Pulse '${key}' must be a function`);
|
|
@@ -89,7 +93,6 @@ function createStore<StateType extends State, PulsesType extends Pulses<StateTyp
|
|
|
89
93
|
|
|
90
94
|
const proxyState = new Proxy(localState, {
|
|
91
95
|
get: (state, prop: string) => {
|
|
92
|
-
// If we are in a pulse, we return the value of the cloned state.
|
|
93
96
|
if (currentState) {
|
|
94
97
|
return currentState[prop];
|
|
95
98
|
}
|
|
@@ -148,38 +151,39 @@ function createStore<StateType extends State, PulsesType extends Pulses<StateTyp
|
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
function getPulseMethod(key: string) {
|
|
151
|
-
function pulseMethod(this:
|
|
154
|
+
function pulseMethod(this: PulseContext, ...args: any[]) {
|
|
152
155
|
pulseCallCount++;
|
|
153
156
|
if (currentState === null) {
|
|
154
157
|
currentState = deepCloneUnfreeze(localState);
|
|
155
158
|
}
|
|
156
159
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
this.$flush = async () => {
|
|
161
|
+
if (currentState) {
|
|
162
|
+
setState(currentState, true);
|
|
163
|
+
currentState = deepCloneUnfreeze(localState);
|
|
164
|
+
}
|
|
160
165
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
161
166
|
};
|
|
162
167
|
|
|
163
|
-
Reflect.set(this, "$flush", $flush);
|
|
164
168
|
const emptyFlush = async () => {};
|
|
165
169
|
|
|
166
170
|
try {
|
|
167
|
-
const pulseResult = pulses[key].apply(this, [currentState, ...args]
|
|
171
|
+
const pulseResult = pulses[key].apply(this, [currentState, ...args]);
|
|
168
172
|
if (pulseResult instanceof Promise) {
|
|
169
173
|
return pulseResult
|
|
170
174
|
.then((resolvedValue) => {
|
|
171
175
|
setState(currentState as StateType);
|
|
172
|
-
|
|
176
|
+
this.$flush = emptyFlush;
|
|
173
177
|
return resolvedValue;
|
|
174
178
|
})
|
|
175
179
|
.catch((error) => {
|
|
176
180
|
console.error(`Error in pulse '${key}':`, error);
|
|
177
|
-
|
|
181
|
+
this.$flush = emptyFlush;
|
|
178
182
|
throw error;
|
|
179
183
|
});
|
|
180
184
|
} else {
|
|
181
185
|
setState(currentState);
|
|
182
|
-
|
|
186
|
+
this.$flush = emptyFlush;
|
|
183
187
|
return pulseResult;
|
|
184
188
|
}
|
|
185
189
|
} catch (error) {
|
|
@@ -226,21 +230,17 @@ function createStore<StateType extends State, PulsesType extends Pulses<StateTyp
|
|
|
226
230
|
}
|
|
227
231
|
const pulseMethod = pulses[prop];
|
|
228
232
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return pulseMethod;
|
|
233
|
+
return (...args: any[]) => {
|
|
234
|
+
const result = pulseMethod.apply(pulseMethod, args);
|
|
235
|
+
if (result instanceof Promise) {
|
|
236
|
+
return result.then((r) => {
|
|
237
|
+
trigger("pulse", prop, args);
|
|
238
|
+
return r;
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
trigger("pulse", prop, args);
|
|
242
|
+
return result;
|
|
243
|
+
};
|
|
244
244
|
}
|
|
245
245
|
});
|
|
246
246
|
|
|
@@ -254,24 +254,16 @@ function createStore<StateType extends State, PulsesType extends Pulses<StateTyp
|
|
|
254
254
|
export function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(
|
|
255
255
|
initialState: StateType,
|
|
256
256
|
pulses: PulsesType
|
|
257
|
-
)
|
|
258
|
-
state: ProxyState<StateType>;
|
|
259
|
-
on: (event: string, callback: Function) => void;
|
|
260
|
-
off: (event: string, callback: Function) => void;
|
|
261
|
-
} {
|
|
257
|
+
) {
|
|
262
258
|
return createStore(initialState, pulses, true);
|
|
263
259
|
}
|
|
264
260
|
|
|
265
261
|
export function createMutableStore<StateType extends State, PulsesType extends Pulses<StateType>>(
|
|
266
262
|
initialState: StateType,
|
|
267
263
|
pulses: PulsesType
|
|
268
|
-
)
|
|
269
|
-
state: ProxyState<StateType>;
|
|
270
|
-
on: (event: string, callback: Function) => void;
|
|
271
|
-
off: (event: string, callback: Function) => void;
|
|
272
|
-
} {
|
|
264
|
+
) {
|
|
273
265
|
console.warn(
|
|
274
|
-
"Warning: You are working with a mutable state.
|
|
266
|
+
"Warning: You are working with a mutable state. All state changes made outside of a pulse will not trigger a re-render."
|
|
275
267
|
);
|
|
276
268
|
return createStore(initialState, pulses, false);
|
|
277
269
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valyrian.js",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.7",
|
|
4
4
|
"description": "Lightweight steel to forge PWAs. (Minimal Frontend Framework with server side rendering and other capabilities)",
|
|
5
5
|
"repository": "git@github.com:Masquerade-Circus/valyrian.js.git",
|
|
6
6
|
"author": "Masquerade <christian@masquerade-circus.net>",
|