solid-new-bucket
Version:
Better Signal API for SolidJS
654 lines (641 loc) • 16.3 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
DisposableCollector: () => DisposableCollector,
DisposableSupport: () => DisposableSupport,
EventSupportedHandleTarget: () => EventSupportedHandleTarget,
HandleTarget: () => HandleTarget,
SimpleEventRegistry: () => SimpleEventRegistry,
Trace: () => Trace,
asAccessor: () => asAccessor,
asBucket: () => asBucket,
bucket: () => bucket,
clone: () => clone,
compareDateString: () => compareDateString,
completeHandle: () => completeHandle,
conditional: () => conditional,
containsAny: () => containsAny,
context: () => context,
copyOfRange: () => copyOfRange,
forward: () => forward,
handle: () => handle,
indexOf: () => indexOf,
isNotEmpty: () => isNotEmpty,
isNumber: () => isNumber,
iterate: () => iterate,
names: () => names,
parseTimestamp: () => parseTimestamp,
removeElementsFromArray: () => removeElementsFromArray,
sequence: () => sequence,
stampedBucket: () => stampedBucket,
terminate: () => terminate,
toCapital: () => toCapital,
useCtx: () => useCtx,
wrapDateNumber: () => wrapDateNumber,
wrapNumber: () => wrapNumber,
wrapString: () => wrapString
});
module.exports = __toCommonJS(src_exports);
// src/arrayHelpers.ts
function removeElementsFromArray(arr, filter) {
const idx = [];
arr.forEach((t, i) => {
if (filter(t)) {
idx.push(i);
}
});
return idx.map((i) => arr.splice(i, 1)[0]);
}
function copyOfRange(arr, start, end) {
const r = [];
start = Math.max(0, start);
end = Math.min(arr.length, end);
for (let i = start; i < end; i++) {
r.push(arr[i]);
}
return r;
}
function indexOf(arr, test) {
for (let i = 0; i < arr.length; i++) {
if (test(arr[i])) {
return i;
}
}
return -1;
}
// src/buckets.ts
var import_solid_js = require("solid-js");
function stampedBucket(value, options) {
if (options?.localStorageName) {
const raw = localStorage.getItem(options.localStorageName);
if (raw) {
if (raw === "undefined") {
value = void 0;
} else {
value = JSON.parse(raw);
}
}
}
const [timestamp, setTimestamp] = (0, import_solid_js.createSignal)(performance.now());
const v = (0, import_solid_js.createMemo)(() => {
return {
timestamp: timestamp(),
data: value,
markChanged() {
setTimestamp(performance.now());
}
};
});
const setV = (newValue) => {
value = newValue;
setTimestamp((/* @__PURE__ */ new Date()).getTime());
};
const call = function(updater) {
if (updater) {
options?.beforeUpdate?.(value);
updater(value);
if (options?.localStorageName) {
localStorage.setItem(options.localStorageName, JSON.stringify(value));
}
setTimestamp((/* @__PURE__ */ new Date()).getTime());
options?.afterUpdate?.(value);
}
return v().data;
};
call.map = (mapper) => {
return mapper(v().data);
};
call.markChanged = () => {
setTimestamp((/* @__PURE__ */ new Date()).getTime());
};
call.reset = (v2) => {
setV(v2);
};
return call;
}
function getFieldOfObject(o, paths) {
for (let i = 0; i < paths.length - 1; i++) {
o = o[paths[i]];
if (!o) {
throw new Error(`cannot find ${paths.join(".")} in ${o}`);
}
}
return o[paths[paths.length - 1]];
}
function setFieldOfObject(o, newValue, paths) {
for (let i = 0; i < paths.length - 1; i++) {
o = o[paths[i]];
if (!o) {
throw new Error(`cannot find ${paths.join(".")} in ${o}`);
}
}
o[paths[paths.length - 1]] = newValue;
}
function asBucket(s, path, mapper) {
const getField = (data) => {
let v = getFieldOfObject(data, path);
return mapper ? mapper.from?.(v) : v;
};
const setField = (data, v) => {
if (mapper) {
v = mapper.to?.(v);
}
setFieldOfObject(data, v, path);
};
return (t) => {
if (t != void 0) {
s((data) => {
if (typeof t === "function") {
const oldValue = getField(data);
setField(data, t(oldValue));
} else {
setField(data, t);
}
});
}
return getField(s());
};
}
function asAccessor(v, k) {
return () => {
if (typeof v === "function") {
return v()[k];
}
return v[k];
};
}
function bucket(value, options) {
if (options?.useValueAsAccessor && typeof value === "function") {
const [_, others2] = (0, import_solid_js.splitProps)(options, ["useValueAsAccessor"]);
const memo = (0, import_solid_js.createMemo)(() => bucket(value(), others2));
return (t) => {
return memo()(t);
};
}
const [local, others] = options && (0, import_solid_js.splitProps)(options, ["beforeUpdate", "afterUpdate", "localStorageName"]) || [];
if (local?.localStorageName) {
const raw = localStorage.getItem(local.localStorageName);
if (raw !== null) {
if (raw === "undefined") {
value = void 0;
} else {
value = JSON.parse(raw);
}
}
}
const [v, setV] = (0, import_solid_js.createSignal)(value, others);
const b = function(t) {
if (t !== void 0) {
const newValue = setV((prev) => {
local?.beforeUpdate?.(prev);
if (typeof t === "function") {
return t(prev);
} else {
return t;
}
});
if (local?.localStorageName) {
localStorage.setItem(local.localStorageName, JSON.stringify(newValue));
}
local?.afterUpdate?.(newValue);
return newValue;
}
return v();
};
Object.defineProperty(b, "value", {
get: function() {
return (0, import_solid_js.untrack)(v);
}
});
return b;
}
// src/checks.ts
function isNotEmpty(v) {
if (!v) return false;
if (typeof v === "string") {
return v.length > 0;
}
if (typeof v === "object") {
if (Array.isArray(v)) {
return v.length > 0;
}
return Object.keys(v).length > 0;
}
return false;
}
function isNumber(v) {
return typeof v === "number";
}
function compareDateString(a, b) {
return Date.parse(a) - Date.parse(b);
}
function containsAny(a, b) {
for (let i of a) {
for (let j of b) {
if (i === j) {
return true;
}
}
}
return false;
}
// src/wrappers.ts
function wrapDateNumber(v, bits = 2) {
if (v == 0) {
return "0".repeat(bits);
}
let n = v;
while (n > 0) {
n = Math.floor(n / 10);
bits--;
}
return bits > 0 ? "0".repeat(bits) + v : v;
}
function wrapString(v) {
if (typeof v === "string") {
return v;
}
return v?.toString() || "";
}
function wrapNumber(v) {
if (typeof v === "number") {
return v;
}
return 0;
}
// src/converters.ts
function parseTimestamp(timestamp, showTime, showMilliseconds) {
const date = new Date(timestamp);
let r = `${wrapDateNumber(date.getFullYear())}-${wrapDateNumber(date.getMonth() + 1)}-${wrapDateNumber(date.getDate())}`;
if (showTime) {
r += ` ${wrapDateNumber(date.getHours())}:${wrapDateNumber(date.getMinutes())}:${wrapDateNumber(date.getSeconds())}`;
}
if (showMilliseconds) {
r += `.${wrapDateNumber(date.getMilliseconds(), 3)}`;
}
;
return r;
}
function toCapital(v) {
return v.charAt(0).toUpperCase() + v.substring(1);
}
// src/generators.ts
function sequence(start, end, step = 1) {
const r = [];
for (let i = start; i < end; i += step) {
r.push(i);
}
return r;
}
function iterate(size) {
return Array.from(Array(size).keys());
}
// src/others.ts
var import_solid_js2 = require("solid-js");
function useCtx(c, displayName) {
const context2 = (0, import_solid_js2.useContext)(c);
if (!context2) {
throw new Error("cannot find a context of " + (displayName || "unknown"));
}
return context2;
}
function context(displayName) {
const ctx = (0, import_solid_js2.createContext)();
const use = function() {
return useCtx(ctx, displayName);
};
return [ctx, use];
}
function names(...v) {
return v.filter((name) => Boolean(name)).join(" ");
}
function clone(obj) {
const type = typeof obj;
switch (type) {
case "object": {
let r = Array.isArray(obj) ? [] : {};
for (let key of Object.keys(obj)) {
r[key] = clone(obj[key]);
}
return r;
}
default:
return obj;
}
}
// src/conditionals.ts
function conditional(condition, value, defaultValue) {
if (typeof value === "function") {
if (condition) {
const r = value();
if (r) {
return r;
}
}
return defaultValue;
}
if (typeof (value === "string")) {
return condition ? value : defaultValue || "";
}
if (typeof value === "number") {
return condition ? value : defaultValue || 0;
}
if (condition) {
return value;
} else if (defaultValue !== void 0 && defaultValue !== null) {
return defaultValue;
}
}
// src/Handle.ts
var import_solid_js4 = require("solid-js");
// src/Disposable.ts
var import_solid_js3 = require("solid-js");
var DisposableSupport = class {
dc = new DisposableCollector();
constructor() {
(0, import_solid_js3.onCleanup)(() => {
this.dc.disposeAll();
});
}
};
var DisposableCollector = class {
dc = [];
size() {
return this.dc.length;
}
collect(disposable) {
this.dc.push(disposable);
}
disposeAll() {
this.dc.forEach((d) => d.dispose());
}
};
// src/SimpleEventRegistry.ts
function forward(params) {
return { action: 0 /* Forward */, params };
}
function terminate(params) {
return { action: 1 /* Terminate */, params };
}
var SimpleEventRegistry = class {
registry = /* @__PURE__ */ new Map();
emit(event, ...args) {
let handlers = this.registry.get(event);
let eventResult;
if (handlers) {
for (const cb of handlers) {
let r = cb(...args);
if (r) {
if (r instanceof Promise) {
throw new Error("emit not support Promise");
}
if (typeof r === "object") {
const { action, params } = r;
if (action === 1 /* Terminate */) {
return params;
} else {
eventResult = params;
}
}
}
}
}
return eventResult;
}
async emitAsync(event, ...args) {
let handlers = this.registry.get(event);
let eventResult;
if (handlers) {
for (const cb of handlers) {
let r = cb(...args);
if (r) {
if (r instanceof Promise) {
r = await r;
}
if (typeof r === "object") {
const { action, params } = r;
if (action === 1 /* Terminate */) {
return params;
} else {
eventResult = params;
}
}
}
}
}
return eventResult;
}
on(event, callback, dc) {
let set = this.registry.get(event);
if (!set) {
set = /* @__PURE__ */ new Set();
this.registry.set(event, set);
}
set.add(callback);
const disposable = { dispose: () => this.off(event, callback) };
if (dc) {
dc.collect(disposable);
} else {
return disposable;
}
}
once(event, callback) {
const disposable = this.on(event, (args) => {
const r = callback(args);
disposable.dispose();
return r;
});
}
off(event, callback) {
let set = this.registry.get(event);
if (set) {
set.delete(callback);
}
}
};
var Trace = class {
constructor(source, parent) {
this.source = source;
this.parent = parent;
}
};
// src/Handle.ts
var ProxyHandlerImpl = class {
target = bucket(null);
mountCallbacks = [];
readyCallbacks = [];
cleanupCallbacks = [];
internalMethods = {
onMount: (callback) => {
if ((0, import_solid_js4.untrack)(this.target)) {
const collector = new DisposableCollector();
callback(collector);
if (collector.size() > 0) {
this.cleanupCallbacks.push(() => {
collector.disposeAll();
});
}
} else {
this.mountCallbacks.push(callback);
}
},
onReady: (callback) => {
if ((0, import_solid_js4.untrack)(this.target)) {
const collector = new DisposableCollector();
callback(collector);
if (collector.size() > 0) {
this.cleanupCallbacks.push(() => {
collector.disposeAll();
});
}
} else {
this.readyCallbacks.push(callback);
}
},
onCleanup: (callback) => {
this.cleanupCallbacks.push(callback);
},
mounted: () => {
return Boolean((0, import_solid_js4.untrack)(this.target));
},
safeAccess: (k) => {
const t = this.target();
if (t) {
const p = t[k];
if (typeof p === "function") {
return p.bind(t);
}
return p;
}
},
mount: (target) => {
this.target(target);
const collector = new DisposableCollector();
this.mountCallbacks.forEach((c) => c(collector));
if (collector.size() > 0) {
this.cleanupCallbacks.push(() => {
collector.disposeAll();
});
}
if (this.readyCallbacks.length > 0) {
(0, import_solid_js4.onMount)(() => {
const collector2 = new DisposableCollector();
this.readyCallbacks.forEach((c) => c(collector2));
if (collector2.size() > 0) {
this.cleanupCallbacks.push(() => {
collector2.disposeAll();
});
}
;
});
}
},
cleanup: () => {
this.cleanupCallbacks.forEach((c) => c());
this.target(null);
}
};
get(_, methodName, proxy) {
if (methodName in this.internalMethods) {
if (methodName === "mounted") {
return this.internalMethods["mounted"]();
}
return this.internalMethods[methodName];
}
const target = (0, import_solid_js4.untrack)(this.target);
if (!target) {
throw new Error(`Target is not mounted yet, cannot access ${String(methodName)}.`);
}
const result = target?.[methodName];
if (typeof result === "function") {
return result.bind(target);
}
return result;
}
};
function handle() {
const handler = new ProxyHandlerImpl();
const proxy = new Proxy({}, handler);
return proxy;
}
function completeHandle(target, handle2) {
if (!handle2) return;
const h = handle2;
(0, import_solid_js4.onMount)(() => {
h.mount(target);
});
(0, import_solid_js4.onCleanup)(() => {
h.cleanup();
});
}
var HandleTarget = class extends DisposableSupport {
constructor(handle2) {
super();
completeHandle(this, handle2);
}
};
var EventSupportedHandleTarget = class extends SimpleEventRegistry {
dc = new DisposableCollector();
constructor(handle2) {
super();
completeHandle(this, handle2);
(0, import_solid_js4.onCleanup)(() => {
this.dc.disposeAll();
});
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DisposableCollector,
DisposableSupport,
EventSupportedHandleTarget,
HandleTarget,
SimpleEventRegistry,
Trace,
asAccessor,
asBucket,
bucket,
clone,
compareDateString,
completeHandle,
conditional,
containsAny,
context,
copyOfRange,
forward,
handle,
indexOf,
isNotEmpty,
isNumber,
iterate,
names,
parseTimestamp,
removeElementsFromArray,
sequence,
stampedBucket,
terminate,
toCapital,
useCtx,
wrapDateNumber,
wrapNumber,
wrapString
});
//# sourceMappingURL=index.js.map