mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-04-04 12:45:54 +02:00
⚡ wip
This commit is contained in:
parent
f8a94ab9f8
commit
f53b97a89c
97
dist/dde-with-signals.js
vendored
97
dist/dde-with-signals.js
vendored
@ -1,6 +1,6 @@
|
|||||||
//deka-dom-el library is available via global namespace `dde`
|
//deka-dom-el library is available via global namespace `dde`
|
||||||
(()=> {
|
(()=> {
|
||||||
// src/signals-lib/signals-common.js
|
// src/signals-lib/common.js
|
||||||
var signals_global = {
|
var signals_global = {
|
||||||
isSignal(attributes) {
|
isSignal(attributes) {
|
||||||
return false;
|
return false;
|
||||||
@ -570,8 +570,36 @@ on.attributeChanged = function(listener, options) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/signals-lib/signals-lib.js
|
// src/signals-lib/helpers.js
|
||||||
var mark = "__dde_signal";
|
var mark = "__dde_signal";
|
||||||
|
var SignalDefined = class extends Error {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
const [curr, ...rest] = this.stack.split("\n");
|
||||||
|
const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
|
||||||
|
this.stack = rest.find((l) => !l.includes(curr_file));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var queueSignalWrite = /* @__PURE__ */ (() => {
|
||||||
|
let pendingSignals = /* @__PURE__ */ new Set();
|
||||||
|
let scheduled = false;
|
||||||
|
function flushSignals() {
|
||||||
|
scheduled = false;
|
||||||
|
for (const signal2 of pendingSignals) {
|
||||||
|
const M = signal2[mark];
|
||||||
|
if (M) M.listeners.forEach((l) => l(M.value));
|
||||||
|
}
|
||||||
|
pendingSignals.clear();
|
||||||
|
}
|
||||||
|
return function(s) {
|
||||||
|
pendingSignals.add(s);
|
||||||
|
if (scheduled) return;
|
||||||
|
scheduled = true;
|
||||||
|
queueMicrotask(flushSignals);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
// src/signals-lib/signals-lib.js
|
||||||
function isSignal(candidate) {
|
function isSignal(candidate) {
|
||||||
return typeof candidate === "function" && hasOwn(candidate, mark);
|
return typeof candidate === "function" && hasOwn(candidate, mark);
|
||||||
}
|
}
|
||||||
@ -602,12 +630,14 @@ function signal(value, actions) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
signal.action = function(s, name, ...a) {
|
signal.action = function(s, name, ...a) {
|
||||||
const M = s[mark], { actions } = M;
|
const M = s[mark];
|
||||||
if (!actions || !(name in actions))
|
if (!M) return;
|
||||||
|
const { actions } = M;
|
||||||
|
if (!actions || !hasOwn(actions, name))
|
||||||
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
|
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
|
||||||
actions[name].apply(M, a);
|
actions[name].apply(M, a);
|
||||||
if (M.skip) return delete M.skip;
|
if (M.skip) return delete M.skip;
|
||||||
M.listeners.forEach((l) => l(M.value));
|
queueSignalWrite(s);
|
||||||
};
|
};
|
||||||
signal.on = function on2(s, listener, options = {}) {
|
signal.on = function on2(s, listener, options = {}) {
|
||||||
const { signal: as } = options;
|
const { signal: as } = options;
|
||||||
@ -621,7 +651,6 @@ signal.symbols = {
|
|||||||
onclear: Symbol.for("Signal.onclear")
|
onclear: Symbol.for("Signal.onclear")
|
||||||
};
|
};
|
||||||
signal.clear = function(...signals2) {
|
signal.clear = function(...signals2) {
|
||||||
console.log("clenaup", signals2);
|
|
||||||
for (const s of signals2) {
|
for (const s of signals2) {
|
||||||
const M = s[mark];
|
const M = s[mark];
|
||||||
if (!M) continue;
|
if (!M) continue;
|
||||||
@ -647,17 +676,15 @@ var storeMemo = /* @__PURE__ */ new WeakMap();
|
|||||||
function memo(key, fun, cache) {
|
function memo(key, fun, cache) {
|
||||||
if (typeof key !== "string") key = JSON.stringify(key);
|
if (typeof key !== "string") key = JSON.stringify(key);
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
const key2 = scope.host();
|
const keyStore = scope.host();
|
||||||
if (storeMemo.has(key2))
|
if (storeMemo.has(keyStore))
|
||||||
cache = storeMemo.get(key2);
|
cache = storeMemo.get(keyStore);
|
||||||
else {
|
else {
|
||||||
cache = {};
|
cache = {};
|
||||||
storeMemo.set(key2, cache);
|
storeMemo.set(keyStore, cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasOwn(cache, key))
|
return hasOwn(cache, key) ? cache[key] : cache[key] = fun();
|
||||||
cache[key] = fun();
|
|
||||||
return cache[key];
|
|
||||||
}
|
}
|
||||||
signal.el = function(s, map) {
|
signal.el = function(s, map) {
|
||||||
const mark_start = createElement.mark({ type: "reactive" }, true);
|
const mark_start = createElement.mark({ type: "reactive" }, true);
|
||||||
@ -766,7 +793,6 @@ function removeSignalsFromElements(s, listener, ...notes) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
var cleanUpRegistry = new FinalizationRegistry(function(s) {
|
var cleanUpRegistry = new FinalizationRegistry(function(s) {
|
||||||
console.log("UNREG");
|
|
||||||
signal.clear({ [mark]: s });
|
signal.clear({ [mark]: s });
|
||||||
});
|
});
|
||||||
function create(is_readonly, value, actions) {
|
function create(is_readonly, value, actions) {
|
||||||
@ -780,14 +806,6 @@ var protoSigal = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|||||||
this.skip = true;
|
this.skip = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var SignalDefined = class extends Error {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
const [curr, ...rest] = this.stack.split("\n");
|
|
||||||
const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
|
|
||||||
this.stack = rest.find((l) => !l.includes(curr_file));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function toSignal(s, value, actions, readonly = false) {
|
function toSignal(s, value, actions, readonly = false) {
|
||||||
const onclear = [];
|
const onclear = [];
|
||||||
if (typeOf(actions) !== "[object Object]")
|
if (typeOf(actions) !== "[object Object]")
|
||||||
@ -828,28 +846,9 @@ function read(s) {
|
|||||||
if (deps.has(context)) deps.get(context).add(s);
|
if (deps.has(context)) deps.get(context).add(s);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
var queueSignalWrite = /* @__PURE__ */ (() => {
|
|
||||||
let pendingSignals = /* @__PURE__ */ new Set();
|
|
||||||
let scheduled = false;
|
|
||||||
function flushSignals() {
|
|
||||||
scheduled = false;
|
|
||||||
for (const signal2 of pendingSignals) {
|
|
||||||
const M = signal2[mark];
|
|
||||||
if (M) M.listeners.forEach((l) => l(M.value));
|
|
||||||
}
|
|
||||||
pendingSignals.clear();
|
|
||||||
}
|
|
||||||
return function(s) {
|
|
||||||
pendingSignals.add(s);
|
|
||||||
if (scheduled) return;
|
|
||||||
scheduled = true;
|
|
||||||
queueMicrotask(flushSignals);
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
function write(s, value, force) {
|
function write(s, value, force) {
|
||||||
if (!s[mark]) return;
|
|
||||||
const M = s[mark];
|
const M = s[mark];
|
||||||
if (!force && M.value === value) return;
|
if (!M || !force && M.value === value) return;
|
||||||
M.value = value;
|
M.value = value;
|
||||||
queueSignalWrite(s);
|
queueSignalWrite(s);
|
||||||
return value;
|
return value;
|
||||||
@ -863,13 +862,13 @@ function removeSignalListener(s, listener, clear_when_empty) {
|
|||||||
if (!M) return;
|
if (!M) return;
|
||||||
const { listeners: L } = M;
|
const { listeners: L } = M;
|
||||||
const out = L.delete(listener);
|
const out = L.delete(listener);
|
||||||
if (clear_when_empty && !L.size) {
|
if (!out || !clear_when_empty || L.size) return out;
|
||||||
signal.clear(s);
|
signal.clear(s);
|
||||||
if (!deps.has(M)) return out;
|
const depList = deps.get(M);
|
||||||
const c = deps.get(M);
|
if (!depList) return out;
|
||||||
if (!deps.has(c)) return out;
|
const depSource = deps.get(depList);
|
||||||
deps.get(c).forEach((sig) => removeSignalListener(sig, c, true));
|
if (!depSource) return out;
|
||||||
}
|
for (const sig of depSource) removeSignalListener(sig, depList, true);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
dist/dde.js
vendored
2
dist/dde.js
vendored
@ -1,6 +1,6 @@
|
|||||||
//deka-dom-el library is available via global namespace `dde`
|
//deka-dom-el library is available via global namespace `dde`
|
||||||
(()=> {
|
(()=> {
|
||||||
// src/signals-lib/signals-common.js
|
// src/signals-lib/common.js
|
||||||
var signals_global = {
|
var signals_global = {
|
||||||
isSignal(attributes) {
|
isSignal(attributes) {
|
||||||
return false;
|
return false;
|
||||||
|
97
dist/esm-with-signals.js
vendored
97
dist/esm-with-signals.js
vendored
@ -1,4 +1,4 @@
|
|||||||
// src/signals-lib/signals-common.js
|
// src/signals-lib/common.js
|
||||||
var signals_global = {
|
var signals_global = {
|
||||||
isSignal(attributes) {
|
isSignal(attributes) {
|
||||||
return false;
|
return false;
|
||||||
@ -568,8 +568,36 @@ on.attributeChanged = function(listener, options) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/signals-lib/signals-lib.js
|
// src/signals-lib/helpers.js
|
||||||
var mark = "__dde_signal";
|
var mark = "__dde_signal";
|
||||||
|
var SignalDefined = class extends Error {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
const [curr, ...rest] = this.stack.split("\n");
|
||||||
|
const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
|
||||||
|
this.stack = rest.find((l) => !l.includes(curr_file));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var queueSignalWrite = /* @__PURE__ */ (() => {
|
||||||
|
let pendingSignals = /* @__PURE__ */ new Set();
|
||||||
|
let scheduled = false;
|
||||||
|
function flushSignals() {
|
||||||
|
scheduled = false;
|
||||||
|
for (const signal2 of pendingSignals) {
|
||||||
|
const M = signal2[mark];
|
||||||
|
if (M) M.listeners.forEach((l) => l(M.value));
|
||||||
|
}
|
||||||
|
pendingSignals.clear();
|
||||||
|
}
|
||||||
|
return function(s) {
|
||||||
|
pendingSignals.add(s);
|
||||||
|
if (scheduled) return;
|
||||||
|
scheduled = true;
|
||||||
|
queueMicrotask(flushSignals);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
// src/signals-lib/signals-lib.js
|
||||||
function isSignal(candidate) {
|
function isSignal(candidate) {
|
||||||
return typeof candidate === "function" && hasOwn(candidate, mark);
|
return typeof candidate === "function" && hasOwn(candidate, mark);
|
||||||
}
|
}
|
||||||
@ -600,12 +628,14 @@ function signal(value, actions) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
signal.action = function(s, name, ...a) {
|
signal.action = function(s, name, ...a) {
|
||||||
const M = s[mark], { actions } = M;
|
const M = s[mark];
|
||||||
if (!actions || !(name in actions))
|
if (!M) return;
|
||||||
|
const { actions } = M;
|
||||||
|
if (!actions || !hasOwn(actions, name))
|
||||||
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
|
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
|
||||||
actions[name].apply(M, a);
|
actions[name].apply(M, a);
|
||||||
if (M.skip) return delete M.skip;
|
if (M.skip) return delete M.skip;
|
||||||
M.listeners.forEach((l) => l(M.value));
|
queueSignalWrite(s);
|
||||||
};
|
};
|
||||||
signal.on = function on2(s, listener, options = {}) {
|
signal.on = function on2(s, listener, options = {}) {
|
||||||
const { signal: as } = options;
|
const { signal: as } = options;
|
||||||
@ -619,7 +649,6 @@ signal.symbols = {
|
|||||||
onclear: Symbol.for("Signal.onclear")
|
onclear: Symbol.for("Signal.onclear")
|
||||||
};
|
};
|
||||||
signal.clear = function(...signals2) {
|
signal.clear = function(...signals2) {
|
||||||
console.log("clenaup", signals2);
|
|
||||||
for (const s of signals2) {
|
for (const s of signals2) {
|
||||||
const M = s[mark];
|
const M = s[mark];
|
||||||
if (!M) continue;
|
if (!M) continue;
|
||||||
@ -645,17 +674,15 @@ var storeMemo = /* @__PURE__ */ new WeakMap();
|
|||||||
function memo(key, fun, cache) {
|
function memo(key, fun, cache) {
|
||||||
if (typeof key !== "string") key = JSON.stringify(key);
|
if (typeof key !== "string") key = JSON.stringify(key);
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
const key2 = scope.host();
|
const keyStore = scope.host();
|
||||||
if (storeMemo.has(key2))
|
if (storeMemo.has(keyStore))
|
||||||
cache = storeMemo.get(key2);
|
cache = storeMemo.get(keyStore);
|
||||||
else {
|
else {
|
||||||
cache = {};
|
cache = {};
|
||||||
storeMemo.set(key2, cache);
|
storeMemo.set(keyStore, cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasOwn(cache, key))
|
return hasOwn(cache, key) ? cache[key] : cache[key] = fun();
|
||||||
cache[key] = fun();
|
|
||||||
return cache[key];
|
|
||||||
}
|
}
|
||||||
signal.el = function(s, map) {
|
signal.el = function(s, map) {
|
||||||
const mark_start = createElement.mark({ type: "reactive" }, true);
|
const mark_start = createElement.mark({ type: "reactive" }, true);
|
||||||
@ -764,7 +791,6 @@ function removeSignalsFromElements(s, listener, ...notes) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
var cleanUpRegistry = new FinalizationRegistry(function(s) {
|
var cleanUpRegistry = new FinalizationRegistry(function(s) {
|
||||||
console.log("UNREG");
|
|
||||||
signal.clear({ [mark]: s });
|
signal.clear({ [mark]: s });
|
||||||
});
|
});
|
||||||
function create(is_readonly, value, actions) {
|
function create(is_readonly, value, actions) {
|
||||||
@ -778,14 +804,6 @@ var protoSigal = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|||||||
this.skip = true;
|
this.skip = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var SignalDefined = class extends Error {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
const [curr, ...rest] = this.stack.split("\n");
|
|
||||||
const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
|
|
||||||
this.stack = rest.find((l) => !l.includes(curr_file));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function toSignal(s, value, actions, readonly = false) {
|
function toSignal(s, value, actions, readonly = false) {
|
||||||
const onclear = [];
|
const onclear = [];
|
||||||
if (typeOf(actions) !== "[object Object]")
|
if (typeOf(actions) !== "[object Object]")
|
||||||
@ -826,28 +844,9 @@ function read(s) {
|
|||||||
if (deps.has(context)) deps.get(context).add(s);
|
if (deps.has(context)) deps.get(context).add(s);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
var queueSignalWrite = /* @__PURE__ */ (() => {
|
|
||||||
let pendingSignals = /* @__PURE__ */ new Set();
|
|
||||||
let scheduled = false;
|
|
||||||
function flushSignals() {
|
|
||||||
scheduled = false;
|
|
||||||
for (const signal2 of pendingSignals) {
|
|
||||||
const M = signal2[mark];
|
|
||||||
if (M) M.listeners.forEach((l) => l(M.value));
|
|
||||||
}
|
|
||||||
pendingSignals.clear();
|
|
||||||
}
|
|
||||||
return function(s) {
|
|
||||||
pendingSignals.add(s);
|
|
||||||
if (scheduled) return;
|
|
||||||
scheduled = true;
|
|
||||||
queueMicrotask(flushSignals);
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
function write(s, value, force) {
|
function write(s, value, force) {
|
||||||
if (!s[mark]) return;
|
|
||||||
const M = s[mark];
|
const M = s[mark];
|
||||||
if (!force && M.value === value) return;
|
if (!M || !force && M.value === value) return;
|
||||||
M.value = value;
|
M.value = value;
|
||||||
queueSignalWrite(s);
|
queueSignalWrite(s);
|
||||||
return value;
|
return value;
|
||||||
@ -861,13 +860,13 @@ function removeSignalListener(s, listener, clear_when_empty) {
|
|||||||
if (!M) return;
|
if (!M) return;
|
||||||
const { listeners: L } = M;
|
const { listeners: L } = M;
|
||||||
const out = L.delete(listener);
|
const out = L.delete(listener);
|
||||||
if (clear_when_empty && !L.size) {
|
if (!out || !clear_when_empty || L.size) return out;
|
||||||
signal.clear(s);
|
signal.clear(s);
|
||||||
if (!deps.has(M)) return out;
|
const depList = deps.get(M);
|
||||||
const c = deps.get(M);
|
if (!depList) return out;
|
||||||
if (!deps.has(c)) return out;
|
const depSource = deps.get(depList);
|
||||||
deps.get(c).forEach((sig) => removeSignalListener(sig, c, true));
|
if (!depSource) return out;
|
||||||
}
|
for (const sig of depSource) removeSignalListener(sig, depList, true);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
dist/esm.js
vendored
2
dist/esm.js
vendored
@ -1,4 +1,4 @@
|
|||||||
// src/signals-lib/signals-common.js
|
// src/signals-lib/common.js
|
||||||
var signals_global = {
|
var signals_global = {
|
||||||
isSignal(attributes) {
|
isSignal(attributes) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export { signal, S, isSignal } from "./src/signals-lib/signals-lib.js";
|
export { signal, S, isSignal } from "./src/signals-lib/signals-lib.js";
|
||||||
import { signals_config } from "./src/signals-lib/signals-lib.js";
|
import { signals_config } from "./src/signals-lib/signals-lib.js";
|
||||||
import { registerReactivity } from "./src/signals-lib/signals-common.js";
|
import { registerReactivity } from "./src/signals-lib/common.js";
|
||||||
registerReactivity(signals_config);
|
registerReactivity(signals_config);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { signals } from "./signals-lib/signals-common.js";
|
import { signals } from "./signals-lib/common.js";
|
||||||
import { enviroment as env } from './dom-common.js';
|
import { enviroment as env } from './dom-common.js';
|
||||||
|
|
||||||
//TODO: add type, docs ≡ make it public
|
//TODO: add type, docs ≡ make it public
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export { registerReactivity } from './signals-lib/signals-common.js';
|
export { registerReactivity } from './signals-lib/common.js';
|
||||||
import { enviroment as env, keyLTE, evc, evd, eva } from './dom-common.js';
|
import { enviroment as env, keyLTE, evc, evd, eva } from './dom-common.js';
|
||||||
|
|
||||||
export function dispatchEvent(name, options, host){
|
export function dispatchEvent(name, options, host){
|
||||||
|
29
src/signals-lib/helpers.js
Normal file
29
src/signals-lib/helpers.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export const mark= "__dde_signal";
|
||||||
|
|
||||||
|
export class SignalDefined extends Error{
|
||||||
|
constructor(){
|
||||||
|
super();
|
||||||
|
const [ curr, ...rest ]= this.stack.split("\n");
|
||||||
|
const curr_file= curr.slice(curr.indexOf("@"), curr.indexOf(".js:")+4);
|
||||||
|
this.stack= rest.find(l=> !l.includes(curr_file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const queueSignalWrite= (()=> {
|
||||||
|
let pendingSignals= new Set();
|
||||||
|
let scheduled= false;
|
||||||
|
|
||||||
|
function flushSignals() {
|
||||||
|
scheduled = false;
|
||||||
|
for(const signal of pendingSignals){
|
||||||
|
const M = signal[mark];
|
||||||
|
if(M) M.listeners.forEach(l => l(M.value));
|
||||||
|
}
|
||||||
|
pendingSignals.clear();
|
||||||
|
}
|
||||||
|
return function(s){
|
||||||
|
pendingSignals.add(s);
|
||||||
|
if(scheduled) return;
|
||||||
|
scheduled = true;
|
||||||
|
queueMicrotask(flushSignals);
|
||||||
|
}
|
||||||
|
})();
|
@ -1,4 +1,5 @@
|
|||||||
export const mark= "__dde_signal";
|
import { SignalDefined, queueSignalWrite, mark } from "./helpers.js";
|
||||||
|
export { mark };
|
||||||
import { hasOwn } from "../helpers.js";
|
import { hasOwn } from "../helpers.js";
|
||||||
|
|
||||||
export function isSignal(candidate){
|
export function isSignal(candidate){
|
||||||
@ -23,8 +24,7 @@ export function signal(value, actions){
|
|||||||
|
|
||||||
const out= create(true);
|
const out= create(true);
|
||||||
function contextReWatch(){
|
function contextReWatch(){
|
||||||
const deps_old= deps.get(contextReWatch);
|
const [ origin, ...deps_old ]= deps.get(contextReWatch);
|
||||||
const origin= deps_old.shift();
|
|
||||||
deps.set(contextReWatch, new Set([ origin ]));
|
deps.set(contextReWatch, new Set([ origin ]));
|
||||||
|
|
||||||
stack_watch.push(contextReWatch);
|
stack_watch.push(contextReWatch);
|
||||||
@ -45,12 +45,14 @@ export function signal(value, actions){
|
|||||||
}
|
}
|
||||||
export { signal as S };
|
export { signal as S };
|
||||||
signal.action= function(s, name, ...a){
|
signal.action= function(s, name, ...a){
|
||||||
const M= s[mark], { actions }= M;
|
const M= s[mark];
|
||||||
if(!actions || !(name in actions))
|
if(!M) return;
|
||||||
|
const { actions }= M;
|
||||||
|
if(!actions || !hasOwn(actions, name))
|
||||||
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
|
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
|
||||||
actions[name].apply(M, a);
|
actions[name].apply(M, a);
|
||||||
if(M.skip) return (delete M.skip);
|
if(M.skip) return (delete M.skip);
|
||||||
M.listeners.forEach(l=> l(M.value));
|
queueSignalWrite(s);
|
||||||
};
|
};
|
||||||
signal.on= function on(s, listener, options= {}){
|
signal.on= function on(s, listener, options= {}){
|
||||||
const { signal: as }= options;
|
const { signal: as }= options;
|
||||||
@ -232,14 +234,6 @@ const protoSigal= Object.assign(Object.create(null), {
|
|||||||
this.skip= true;
|
this.skip= true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
class SignalDefined extends Error{
|
|
||||||
constructor(){
|
|
||||||
super();
|
|
||||||
const [ curr, ...rest ]= this.stack.split("\n");
|
|
||||||
const curr_file= curr.slice(curr.indexOf("@"), curr.indexOf(".js:")+4);
|
|
||||||
this.stack= rest.find(l=> !l.includes(curr_file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function toSignal(s, value, actions, readonly= false){
|
function toSignal(s, value, actions, readonly= false){
|
||||||
const onclear= [];
|
const onclear= [];
|
||||||
if(typeOf(actions)!=="[object Object]")
|
if(typeOf(actions)!=="[object Object]")
|
||||||
@ -277,29 +271,10 @@ function read(s){
|
|||||||
if(deps.has(context)) deps.get(context).add(s);
|
if(deps.has(context)) deps.get(context).add(s);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
const queueSignalWrite= (()=> {
|
|
||||||
let pendingSignals= new Set();
|
|
||||||
let scheduled= false;
|
|
||||||
|
|
||||||
function flushSignals() {
|
|
||||||
scheduled = false;
|
|
||||||
for(const signal of pendingSignals){
|
|
||||||
const M = signal[mark];
|
|
||||||
if(M) M.listeners.forEach(l => l(M.value));
|
|
||||||
}
|
|
||||||
pendingSignals.clear();
|
|
||||||
}
|
|
||||||
return function(s){
|
|
||||||
pendingSignals.add(s);
|
|
||||||
if(scheduled) return;
|
|
||||||
scheduled = true;
|
|
||||||
queueMicrotask(flushSignals);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
function write(s, value, force){
|
function write(s, value, force){
|
||||||
const M= s[mark];
|
const M= s[mark];
|
||||||
if(!M || (!force && M.value===value)) return;
|
if(!M || (!force && M.value===value)) return;
|
||||||
|
|
||||||
M.value= value;
|
M.value= value;
|
||||||
queueSignalWrite(s);
|
queueSignalWrite(s);
|
||||||
return value;
|
return value;
|
||||||
@ -312,7 +287,7 @@ function addSignalListener(s, listener){
|
|||||||
function removeSignalListener(s, listener, clear_when_empty){
|
function removeSignalListener(s, listener, clear_when_empty){
|
||||||
const M= s[mark];
|
const M= s[mark];
|
||||||
if(!M) return;
|
if(!M) return;
|
||||||
|
|
||||||
const { listeners: L }= M;
|
const { listeners: L }= M;
|
||||||
const out= L.delete(listener);
|
const out= L.delete(listener);
|
||||||
if(!out || !clear_when_empty || L.size) return out;
|
if(!out || !clear_when_empty || L.size) return out;
|
||||||
@ -320,10 +295,10 @@ function removeSignalListener(s, listener, clear_when_empty){
|
|||||||
signal.clear(s);
|
signal.clear(s);
|
||||||
const depList= deps.get(M);
|
const depList= deps.get(M);
|
||||||
if(!depList) return out;
|
if(!depList) return out;
|
||||||
|
|
||||||
const depSource= deps.get(depList);
|
const depSource= deps.get(depList);
|
||||||
if(!depSource) return out;
|
if(!depSource) return out;
|
||||||
|
|
||||||
for(const sig of depSource) removeSignalListener(sig, depList, true);
|
for(const sig of depSource) removeSignalListener(sig, depList, true);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user