@msom/reaction
Version:
@msom/reaction
897 lines (885 loc) • 26.5 kB
JavaScript
//#region ../common/dist/index.js
function assert(condition, message = "") {
if (!condition) throw Error(message);
}
/**
* 集合类,提供基于键值的元素存储和管理
* @template T 元素类型
*/
var Collection = class {
/**
* 创建集合实例
* @param getKey 获取元素键值的函数
*/
constructor(getKey) {
assert(getKey, "miss get unique key");
this.getKey = getKey;
this.elements = new Array();
this.elMap = /* @__PURE__ */new Map();
this.indexMap = /* @__PURE__ */new Map();
}
/**
* 获得集合的实际元素数量
*/
size() {
return Reflect.ownKeys(this.elements).length;
}
/**
* 根据键值获取元素
* @param key 元素的键值
* @returns 对应的元素或undefined
*/
get(key) {
return this.elMap.get(key);
}
/**
* 检查是否存在指定键值的元素
* @param key 要检查的键值
* @returns 是否存在
*/
hasKey(key) {
return this.elMap.has(key);
}
/**
* 检查元素是否在集合中
* @param element 要检查的元素
* @returns 是否存在
*/
hasElement(element) {
return this.hasKey(this.getKey(element));
}
/**
* 添加元素到集合
* @param element 要添加的元素
* @param force 当元素已存在时是否强制替换,默认为false
*/
add(element, force) {
const key = this.getKey(element);
const has = this.elMap.has(key);
if (!has) {
const index = this.elements.push(element) - 1;
this.indexMap.set(key, index);
this.elMap.set(key, element);
} else if (force) {
const index = this.indexMap.get(key);
assert(index);
this.elMap.set(key, element);
this.elements.splice(index, 1, element);
}
}
/**
* 使用指定的键值添加元素
* @param key 指定的键值
* @param element 要添加的元素
* @param force 当键值已存在时是否强制替换,默认为false
*/
addKey(key, element, force) {
const has = this.elMap.has(key);
if (!has) {
const index = this.elements.push(element) - 1;
this.indexMap.set(key, index);
this.elMap.set(key, element);
} else if (force) {
const index = this.indexMap.get(key);
assert(index != void 0);
this.elMap.set(key, element);
this.elements.splice(index, 1, element);
}
}
/**
* 批量添加元素
* @param iterator 可迭代的元素集合
* @param force 当元素已存在时是否强制替换,默认为false
*/
addAll(iterator$1, force) {
const { next } = iterator$1[Symbol.iterator]();
let result = next();
while (!result.done) {
this.add(result.value, force);
result = next();
}
}
/**
* 在指定位置插入元素
* @param element 待插入的元素
* @param index 插入位置,范围[0, length]。如果超出范围会被自动调整到有效范围内
* @param exist 当元素已存在时的处理选项
* @param exist.index 是否保持原有元素的位置。true: 保持原位置,false: 使用新位置
* @param exist.element 是否使用新元素替换原有元素。true: 使用新元素,false: 保持原有元素
*/
insert(element, index, exist) {
const key = this.getKey(element);
const has = this.elMap.has(key);
const { index: cIndex, element: cElement } = exist || {};
if (!has) {
this.elMap.set(key, element);
index = Math.min(this.elements.length, Math.max(0, index));
this.elements.splice(index, 0, element);
} else {
const oIndex = this.indexMap.get(key);
assert(oIndex);
const oElement = this.elements[oIndex];
const placeholder = Symbol("placegholder");
this.elements[oIndex] = placeholder;
if (!cIndex) index = oIndex;
if (!cElement) element = oElement;
this.elements.splice(index, 0, element);
this.elements = this.elements.filter((v) => v !== placeholder);
this.updateIndexMap();
}
}
/**
* 移除指定元素
* @param element 要移除的元素
* @returns 是否成功移除
*/
removeElement(element) {
const key = this.getKey(element);
return !!this.remove(key);
}
/**
* 根据键值移除元素
* @param key 要移除的元素的键值
* @returns 被移除的元素,如果元素不存在则返回undefined
*/
remove(key) {
const has = this.elMap.has(key);
if (has) {
const index = this.indexMap.get(key);
assert(index);
this.elements.splice(index, 1);
this.updateIndexMap();
this.elMap.delete(key);
}
return void 0;
}
/**
* 清空集合中的所有元素
*/
clear() {
this.elMap.clear();
this.elements.length = 0;
this.indexMap.clear();
}
/**
* 更新索引映射
* 当元素数组发生变化时,需要重新计算每个元素的索引
* @private
*/
updateIndexMap() {
const { elements, indexMap } = this;
const { length } = elements;
indexMap.clear();
for (let i = 0; i < length; i++) {
const element = elements[i];
const key = this.getKey(element);
indexMap.set(key, i);
}
}
/**
* 实现Iterable接口,使集合可以被迭代
* 使用生成器函数遍历集合中的所有元素
* @yields 集合中的每个元素
*/
[Symbol.iterator]() {
let i = 0;
return { next: () => {
const j = i;
i++;
return {
value: this.elements[j],
done: j >= this.elements.length
};
} };
}
/**
* 遍历集合中的所有元素
* @param handler 处理每个元素的回调函数
*/
each(handler) {
this.elMap.forEach((el, k) => handler(el, k, this));
}
toArray(filter, mapper) {
const result = [];
const elements = this.elements;
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
const key = this.getKey(element);
if (filter && !filter(element, key, this)) continue;
const value = mapper ? mapper(element, key, this) : element;
result.push(value);
}
return result;
}
};
const symbolKeys = new Collection((keys) => keys.key);
function GeneratSymbolKey(key) {
if (symbolKeys.hasKey(key)) return symbolKeys.get(key).symbolKey;else
{
const symbolKey = Symbol(key);
symbolKeys.add({
key,
symbolKey
});
return symbolKey;
}
}
function setGlobalData(key, data) {
const symbolKey = GeneratSymbolKey(key);
Object.assign(globalThis, { [symbolKey]: data });
return data;
}
function getGlobalData(key) {
const symbolKey = GeneratSymbolKey(key);
const data = Reflect.get(globalThis, symbolKey);
if (!data) {
if (key.startsWith("@msom/")) throw `The GlobalData of ${key} is must init before get.`;
return setGlobalData(key, {});
}
return data;
}
const ENUMERABLE = 4;
const WRITABLE = 2;
const CONFIGURABLE = 1;
/**
* @param target
* @param propKey
* @param flag 7
* * const enumerable = 0x04;
* * const writable = 0x02;
* * const configurable = 0x01;
* @param value
*/
function defineProperty(target, propKey, flag = 7, value) {
Object.defineProperty(target, propKey, {
value,
writable: !!(WRITABLE & flag),
enumerable: !!(ENUMERABLE & flag),
configurable: !!(CONFIGURABLE & flag)
});
}
/**
* @param target
* @param propKey
* @param flag 5
* * const enumerable = 0x04;
* * const writable = 0x02;
* * const configurable = 0x01;
* * 访问器属性修饰符无法设置writable
* @param getter
* @param setter
*/
function defineAccesser(target, propKey, flag = 5, getter, setter) {
Object.defineProperty(target, propKey, {
enumerable: !!(ENUMERABLE & flag),
configurable: !!(CONFIGURABLE & flag),
get: getter,
set: setter
});
}
function equal(value, otherValue) {
return Object.is(value, otherValue);
}
const EVENTS = Symbol("__EVENTS__");
const FRAME_INTERVAL = 1e3 / 60;
const TYPE_SPLITOR = ",";
const OVERlOAD_KEY = Symbol("overload");
const ADD_IMPLEMENT = "addImplement";
/**
* 创建一个可重载的函数
* @template T 类型数组的数组,每个数组最后一个类型为返回值类型
*/
function createOverload(impls) {
const overloadCollection = new Collection((m) => {
return Reflect.get(m, OVERlOAD_KEY);
});
const Method = {
method(...args) {
const overloadKey = args.map((v) => typeof v).join(TYPE_SPLITOR);
const overload = overloadCollection.get(overloadKey);
assert(overload, "No implementation found");
return overload.apply(this, args);
},
add(...impl) {
const overload = impl.pop();
if (typeof overload !== "function") throw Error("The last parameter must be a function");
const overloadKey = impl.join(TYPE_SPLITOR);
overloadCollection.addKey(overloadKey, overload, true);
}
};
defineProperty(Method.method, ADD_IMPLEMENT, 0, Method.add);
if (impls) for (const impl of impls) Method.add(...impl);
return Method.method;
}
/**
* 使用示例
*/
const example = createOverload([
[
"string",
"number",
(a, c = 1) => Number(a) + c],
["string", (a) => a],
["number", (a) => a]]
);
example("1", 2);
example("1");
example(1);
example[ADD_IMPLEMENT]("string", "number", (a, c = 1) => Number(a) + c);
const onlyUsedMap = {
observer: "observer decorator only be used with instance property.",
option: "option decorator only be used with instance property or accessor property for setter.",
component: "component decorator only be used with class.",
computed: "computed decorator only be used with instance method or accessor property for getter."
};
function decoratorUsedErrorOptionHandler(decoratorName, option) {
const { defineMessage } = option;
if (defineMessage) return typeof defineMessage === "function" ? defineMessage() : defineMessage;
const should = [
"(",
onlyUsedMap[decoratorName],
")"];
let notIndex = "";
if (option.NotStatic) notIndex = "static property or method";else
if (option.NotInComponent) notIndex = "outside a Component";else
if (option.NotSetter) notIndex = "accessor property for not setter";else
if (option.NotMethod) notIndex = "a instance method";else
if (option.NotAccessor) notIndex = "accessor property";else
if (option.NotClass) notIndex = "not a class";else
if (option.NotProperty) notIndex = "a instance property";
return `${notIndex ? `not allow used with ${notIndex}.` : ""} ${notIndex ? should.join("") : should[1]}`.trim();
}
/**
* class: ObserverDUE
*/
var ObserverDUE = class extends Error {
constructor(option = {}) {
super(decoratorUsedErrorOptionHandler("observer", option));
}
};
const ObserverDecoratorUsedError = ObserverDUE;
/**
* class: ComputedDUE
*/
var ComputedDUE = class extends Error {
constructor(option = {}) {
super(decoratorUsedErrorOptionHandler("computed", option));
}
};
const ComputedDecoratorUsedError = ComputedDUE;
function isObject(value) {
return typeof value === "object" && value !== null;
}
const componentGlobalData = setGlobalData("@msom/component", {
componentDefinitionKey: Symbol("component_definition"),
componentMap: /* @__PURE__ */new Map()
});
/**
* 初始化组件定义
* 不会向上继续找原型对象的原型
* @param prototype 组件类或类的原型对象
* @returns 组件定义
*/
function initComponentDefinition(prototype) {
const { componentDefinitionKey } = componentGlobalData;
prototype = typeof prototype === "function" ? prototype.prototype : prototype;
const prototype_prototype = Object.getPrototypeOf(prototype);
const prototype_prototype_definition = getComponentDefinition(prototype_prototype);
try {
Object.setPrototypeOf(prototype, null);
let definition = Reflect.get(prototype, componentDefinitionKey);
if (!definition) {
definition = Object.create(null);
assert(definition);
Object.assign(definition, {
$options: Object.create(prototype_prototype_definition?.["$options"] || null),
$events: Object.create(prototype_prototype_definition?.["$events"] || null),
$observers: Object.create(prototype_prototype_definition?.["$observers"] || null)
});
defineProperty(prototype, componentDefinitionKey, 0, definition);
}
return definition;
} finally {
Object.setPrototypeOf(prototype, prototype_prototype);
}
}
/**
* @param prototype 组件类或类的原型对象
* @returns 组件定义
*/
function getComponentDefinition(prototype) {
const { componentDefinitionKey } = componentGlobalData;
prototype = typeof prototype === "function" ? prototype.prototype : prototype;
const oldProptotype = Object.getPrototypeOf(prototype);
try {
Object.setPrototypeOf(prototype, null);
return Reflect.get(prototype, componentDefinitionKey);
} finally {
Object.setPrototypeOf(prototype, oldProptotype);
}
}
/**
* 判断是否使用 @component 装饰器标记
* @param ctor 类构造器或原型对象
* @returns
*/
function isComponent(ctor) {
const { componentDefinitionKey } = componentGlobalData;
const target = typeof ctor === "function" ? ctor.prototype : ctor;
const prototype = Object.getPrototypeOf(target);
try {
Object.setPrototypeOf(target, null);
return Reflect.has(target, componentDefinitionKey);
} finally {
Object.setPrototypeOf(target, prototype);
}
}
//#endregion
//#region src/Reaction/index.ts
setGlobalData("@msom/reaction", {});
var Reaction = class {
constructor(option) {
this.tracked = /* @__PURE__ */new Set();
this.option = option;
this.updateNextTick();
this.track();
}
_cancel() {
this.cancel && this.cancel();
this.cancel = void 0;
}
/**
* 根据传入的delay选项,初始化微队列函数
* @returns
*/
updateNextTick() {
const { scheduler } = this.option;
if (!scheduler) return;
if (scheduler === "nextTick") {if (typeof process !== "undefined" && process.nextTick) this.nextTick = function (cb) {
this._cancel();
let canceled = false;
process.nextTick(() => {
if (!canceled) cb();
this.cancel = void 0;
});
this.cancel = () => {
canceled = true;
};
};else
this.nextTick = function (cb) {
this._cancel();
let canceled = false;
queueMicrotask(() => {
if (!canceled) cb();
this.cancel = void 0;
});
this.cancel = () => {
canceled = true;
};
};} else
if (scheduler === "nextFrame") this.nextTick = function (cb) {
this._cancel();
if (Reflect.has(globalThis, "requestAnimationFrame")) {
const rafId = requestAnimationFrame(() => {
cb();
this.cancel = void 0;
});
this.cancel = () => {
cancelAnimationFrame(rafId);
this.cancel = void 0;
};
} else {
const id = setTimeout(() => {
cb();
this.cancel = void 0;
}, 1e3 / 60);
this.cancel = () => {
clearTimeout(id);
this.cancel = void 0;
};
}
};else
this.nextTick = scheduler;
}
nextTick(cb) {
this._cancel();
cb();
}
track() {
const { tracker } = this.option;
this.destroy();
const reactionData = getGlobalData("@msom/reaction");
const { tracking, reaction } = reactionData;
try {
Object.assign(reactionData, {
tracking: this.addObserver.bind(this),
reaction: this
});
tracker();
} catch (e) {
this.destroy();
console.error(e);
} finally {
Object.assign(reactionData, {
tracking,
reaction
});
}
}
notify() {
const { reaction } = getGlobalData("@msom/reaction");
if (reaction && reaction === this) console.error("The value of the dependent observer is being changed in the current tracking");else
this.nextTick(() => {
this.runcall();
});
}
exec() {
this.runcall();
return this;
}
runcall() {
const { callback } = this.option;
callback ? callback() : this.track();
}
disposer() {
return this.destroy.bind(this);
}
destroy() {
this.tracked.forEach(this.removeObserver.bind(this));
}
addObserver(observer$1) {
this.tracked.add(observer$1);
observer$1.addReaction(this);
}
removeObserver(observer$1) {
this.tracked.delete(observer$1);
observer$1.removeReaction(this);
}
};
function createReaction(tracker, callback, option) {
if (typeof callback === "function") return new Reaction({
tracker,
callback,
scheduler: option?.scheduler
});else
if (callback) {
if (option) throw "error params.";
return new Reaction({
tracker,
scheduler: callback.scheduler
});
} else return new Reaction({
tracker,
scheduler: option?.scheduler
});
}
function withoutTrack(callback) {
const reactionData = getGlobalData("@msom/reaction");
const { tracking, reaction } = reactionData;
reactionData.tracking = void 0;
reactionData.reaction = void 0;
try {
return callback();
} catch (e) {
throw e;
} finally {
Object.assign(reactionData, {
tracking,
reaction
});
}
}
//#endregion
//#region src/Operator/index.ts
const iterator = Symbol.iterator;
const OPERATORTYPES = {
TRACKER: {
GET: "GET",
HAS: "HAS",
[iterator]: iterator
},
TRRIGER: {
SET: "SET",
ADD: "ADD",
DELETE: "DELETE"
}
};
const OPERATORMAPS = {
[OPERATORTYPES.TRRIGER.SET]: [OPERATORTYPES.TRACKER.GET],
[OPERATORTYPES.TRRIGER.ADD]: [
OPERATORTYPES.TRACKER.GET,
OPERATORTYPES.TRACKER.HAS,
OPERATORTYPES.TRACKER[iterator]],
[OPERATORTYPES.TRRIGER.DELETE]: [
OPERATORTYPES.TRACKER.GET,
OPERATORTYPES.TRACKER.HAS,
OPERATORTYPES.TRACKER[iterator]]
};
Object.freeze(OPERATORTYPES);
Object.freeze(OPERATORMAPS);
//#endregion
//#region src/Observer/index.ts
var Observer = class {
constructor(option = {}) {
this.equal = option.equal || equal;
this.handlers = /* @__PURE__ */new Set();
if (Object.prototype.hasOwnProperty.call(option, "initValue")) {
const value = option.initValue;
assert(value);
this.value = value;
}
}
track() {
const running = getGlobalData("@msom/reaction");
if (running?.tracking) running.tracking(this);
}
get() {
this.track();
return this.value;
}
set(newValue) {
const { value: oldValue } = this;
this.value = newValue;
if (!this.equal(oldValue, newValue)) this.notify();
}
notify() {
const handles = [...this.handlers];
for (const reaction of handles) reaction.notify();
}
addReaction(reaction) {
this.handlers.add(reaction);
}
removeReaction(reaction) {
this.handlers.delete(reaction);
}
destroy() {
this.handlers.forEach((reaction) => {
reaction.removeObserver(this);
});
}
};
function getObserverForce(target, propKey, trackType) {
let _target = targetMap.get(target);
if (!_target) targetMap.set(target, _target = { propMap: /* @__PURE__ */new Map() });
if (!_target.propMap) _target.propMap = /* @__PURE__ */new Map();
const propMap = _target.propMap;
let typesMap = propMap.get(propKey);
if (!typesMap) propMap.set(propKey, typesMap = /* @__PURE__ */new Map());
let observer$1 = typesMap.get(trackType);
if (!observer$1) typesMap.set(trackType, observer$1 = new Observer());
return observer$1;
}
function getObserver$1(target, propKey, trackType) {
return targetMap.get(target)?.propMap?.get(propKey)?.get(trackType);
}
const targetMap = /* @__PURE__ */new WeakMap();
function track(target, propKey, trackType) {
getObserverForce(target, propKey, trackType).track();
}
function trriger(target, propKey, trrigerType, destroy) {
const trackTypes = OPERATORMAPS[trrigerType];
for (const trackType of trackTypes) {
const observer$1 = getObserver$1(target, propKey, trackType);
if (!observer$1) continue;
observer$1.notify();
destroy && observer$1.destroy();
}
}
const reactiveOptions = {
get(target, propKey, receiver) {
const value = Reflect.get(target, propKey, receiver);
track(target, propKey, OPERATORTYPES.TRACKER.GET);
return isObject(value) ? reactive(value) : value;
},
has(target, propKey) {
const result = Reflect.has(target, propKey);
track(target, propKey, OPERATORTYPES.TRACKER.HAS);
return result;
},
ownKeys(target) {
const result = Reflect.ownKeys(target);
track(target, Symbol.iterator, OPERATORTYPES.TRACKER[Symbol.iterator]);
return result;
},
set(target, propKey, value, receiver) {
const result = Reflect.set(target, propKey, value, receiver);
let trrigerType = Reflect.has(target, propKey) ? OPERATORTYPES.TRRIGER.SET : OPERATORTYPES.TRRIGER.ADD;
if (result) trriger(target, propKey, trrigerType);
return result;
},
deleteProperty(target, propKey) {
const result = Reflect.deleteProperty(target, propKey);
if (result) {
const _target = targetMap.get(target);
if (_target && _target.propMap && _target.propMap.has(propKey)) {
trriger(target, propKey, OPERATORTYPES.TRRIGER.DELETE, true);
_target.propMap.delete(propKey);
}
}
return result;
}
};
function reactive(target) {
let _target = targetMap.get(target);
if (!_target) {
_target = {
propMap: /* @__PURE__ */new Map(),
proxy: new Proxy(target, reactiveOptions)
};
targetMap.set(target, _target);
}
if (!_target.proxy) _target.proxy = new Proxy(target, reactiveOptions);
return _target.proxy;
}
//#endregion
//#region src/Computed/index.ts
var Computed = class {
constructor(props) {
Object.assign(this, props);
this.dirty = true;
}
track() {
const running = getGlobalData("@msom/reaction");
if (running?.tracking) running.tracking(this);
}
get() {
this.track();
if (!this.dirty && true) return this.cache;else
{
this.compute();
return this.cache;
}
}
compute() {
const { method } = this;
if (!method) return;
this.subReaction?.destroy();
this.subReaction = createReaction(() => {
this.cache = method();
this.dirty = false;
}, () => {
this.notify();
});
}
notify() {
this.dirty = true;
const handles = [...this.handles];
for (const reaction of handles) reaction.notify();
}
addReaction(reaction) {
this.handles.add(reaction);
}
removeReaction(reaction) {
this.handles.delete(reaction);
}
destroy() {
this.dirty = true;
this.subReaction?.destroy();
this.subReaction = void 0;
this.handles.forEach((reaction) => {
reaction.removeObserver(this);
});
}
};
//#endregion
//#region src/utils.ts
const observerMapSymbolKey = Symbol("observerMapSymbolKey");
function getObserver(key) {
const observersMap = Reflect.get(this, observerMapSymbolKey, this);
if (!observersMap) return;
const observer$1 = observersMap.get(key);
if (!observer$1) return;
return observer$1;
}
const _observer = "observer";
const _computed = "computed";
const observerTypeMap = {
[_observer]: Observer,
[_computed]: Computed
};
function generateIObserver(key, type, option) {
const observersMap = Reflect.get(this, observerMapSymbolKey, this) || /* @__PURE__ */new Map();
Reflect.set(this, observerMapSymbolKey, observersMap, this);
const observer$1 = observersMap.get(key) || new observerTypeMap[type](option);
observersMap.set(key, observer$1);
return observer$1;
}
//#endregion
//#region src/decorators/observer.ts
function observer(option = {}) {
return function (target, key) {
if (typeof target === "function") throw new ObserverDecoratorUsedError({ NotStatic: true });
const descriptor = Object.getOwnPropertyDescriptor(target, key);
if (descriptor) {
if (typeof descriptor.value === "function") throw new ObserverDecoratorUsedError({ NotMethod: true });
throw new ObserverDecoratorUsedError({ NotAccessor: true });
}
if (isComponent(target)) {
const definition = initComponentDefinition(target);
if (Reflect.has(definition.$observers, key)) throw new ObserverDecoratorUsedError({ defineMessage() {
return `the observer property ${String(key)} is exist.`;
} });
defineProperty(definition.$observers, key, 7, "observer");
}
defineAccesser(target, key, 5, function () {
return generateIObserver.bind(this)(key, _observer, option).get();
}, function (value) {
return generateIObserver.bind(this)(key, _observer, option).set(value);
});
};
}
//#endregion
//#region src/decorators/computed.ts
/**
* 计算属性装饰器
* 用于get计算属性和无参函数上
* @returns MethodDecorator
*/
function computed(option) {
return function (target, key, descriptor) {
if (typeof target === "function") throw new ComputedDecoratorUsedError({ NotStatic: true });
if (!descriptor) throw new ComputedDecoratorUsedError({ NotProperty: true });
let method = descriptor.value;
let methodType = "value";
if (typeof method !== "function") {
method = descriptor.get;
methodType = "get";
}
if (typeof method !== "function") throw new ComputedDecoratorUsedError({ defineMessage: () => {
return `the method or accessor for getter ${String(key)} not be function.`;
} });
if (method.length > 0) {
console.warn(new ComputedDecoratorUsedError({ defineMessage: () => {
return "the computed effct method should be no argument";
} }).message);
return;
}
if (isComponent(target)) {
const definition = initComponentDefinition(target);
if (Reflect.has(definition.$observers, key) && definition.$observers[key]) throw new ComputedDecoratorUsedError({ defineMessage: () => {
return `the computed method or computed property ${String(key)} is exist.`;
} });
defineProperty(definition.$observers, key, 7, "computed");
}
const _method = method;
descriptor[methodType] = function () {
const create = generateIObserver.bind(this);
return create(key, _computed, {
...option,
method: _method.bind(this)
}).get();
};
const setter = descriptor.set;
if (setter) descriptor.set = function (value) {
setter.call(this, value);
const create = generateIObserver.bind(this);
create(key, _computed, {
...option,
method: _method.bind(this)
}).notify();
};
};
}
//#endregion
export { Computed, Observer, Reaction, computed, createReaction, getObserver, observer, reactive, withoutTrack };
//# sourceMappingURL=index.js.map