feat: update signals version

main
CCherry07 8 months ago
parent 7528d0fda4
commit f3cea8ef0e
  1. 2
      package.json
  2. 20
      pnpm-lock.yaml
  3. 17
      src/computed.ts
  4. 3
      src/contents.ts
  5. 212
      src/core.ts
  6. 5
      src/deepSignal.ts
  7. 3
      src/index.ts
  8. 26
      src/signal.ts
  9. 4
      tsconfig.json
  10. 1
      tsup.config.ts

@ -24,7 +24,7 @@
"release": "bumpp && npm run build && npm publish --registry=https://registry.npmjs.org/" "release": "bumpp && npm run build && npm publish --registry=https://registry.npmjs.org/"
}, },
"dependencies": { "dependencies": {
"alien-signals": "latest" "alien-signals": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"bumpp": "^9.9.2", "bumpp": "^9.9.2",

@ -9,8 +9,8 @@ importers:
.: .:
dependencies: dependencies:
alien-signals: alien-signals:
specifier: latest specifier: 1.0.0
version: 0.6.0 version: 1.0.0
devDependencies: devDependencies:
bumpp: bumpp:
specifier: ^9.9.2 specifier: ^9.9.2
@ -375,51 +375,61 @@ packages:
resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==} resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.29.1': '@rollup/rollup-linux-arm-musleabihf@4.29.1':
resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==} resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.29.1': '@rollup/rollup-linux-arm64-gnu@4.29.1':
resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==} resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.29.1': '@rollup/rollup-linux-arm64-musl@4.29.1':
resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==} resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.29.1': '@rollup/rollup-linux-loongarch64-gnu@4.29.1':
resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==} resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-powerpc64le-gnu@4.29.1': '@rollup/rollup-linux-powerpc64le-gnu@4.29.1':
resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==} resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.29.1': '@rollup/rollup-linux-riscv64-gnu@4.29.1':
resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==} resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-s390x-gnu@4.29.1': '@rollup/rollup-linux-s390x-gnu@4.29.1':
resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==} resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.29.1': '@rollup/rollup-linux-x64-gnu@4.29.1':
resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==} resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.29.1': '@rollup/rollup-linux-x64-musl@4.29.1':
resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==} resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-win32-arm64-msvc@4.29.1': '@rollup/rollup-win32-arm64-msvc@4.29.1':
resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==} resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==}
@ -476,8 +486,8 @@ packages:
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
hasBin: true hasBin: true
alien-signals@0.6.0: alien-signals@1.0.0:
resolution: {integrity: sha512-2uVYGg0IY07glpXb7uu+mGuJFxEO0Blp3c3bagwxK9E5Fh6AKcXoUb7iDaa584FW7vEKPoNoy+2UOy39/eLiwg==} resolution: {integrity: sha512-Fd2sYMdyjWD6VKxeewCYHXsIYAiELGMtQzGJ6vyxpxtQ1exXYiNTynSqGllkk+mOqhtBFYcC1Qvb49FbCSvsQw==}
ansi-regex@5.0.1: ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
@ -1386,7 +1396,7 @@ snapshots:
acorn@8.14.0: {} acorn@8.14.0: {}
alien-signals@0.6.0: {} alien-signals@1.0.0: {}
ansi-regex@5.0.1: {} ansi-regex@5.0.1: {}

@ -1,17 +0,0 @@
import { Computed as AlienComputed } from 'alien-signals';
export function computed<T>(getter: (cachedValue?: T) => T): Computed<T> {
return new Computed<T>(getter);
}
export class Computed<T = any> extends AlienComputed {
constructor(getter: (cachedValue?: T) => T) {
super(getter);
}
get value(): T {
return this.get();
}
peek(): T {
return this.currentValue;
}
}

@ -0,0 +1,3 @@
export enum ReactiveFlags {
IS_REFERENCE = '__v_isReference',
}

@ -0,0 +1,212 @@
import { createReactiveSystem, Dependency, Link, Subscriber, SubscriberFlags } from 'alien-signals';
import { ReactiveFlags } from "./contents"
const {
link,
propagate,
endTracking,
startTracking,
updateDirtyFlag,
processComputedUpdate,
processEffectNotifications,
} = createReactiveSystem({
updateComputed(computed: Computed) {
return computed.update();
},
notifyEffect(effect: Effect) {
effect.notify();
return true;
},
});
let activeSub: Subscriber | undefined = undefined;
let batchDepth = 0;
export function startBatch(): void {
++batchDepth;
}
export function endBatch(): void {
if (!--batchDepth) {
processEffectNotifications();
}
}
export function signal<T>(): Signal<T | undefined>;
export function signal<T>(oldValue: T): Signal<T>;
export function signal<T>(oldValue?: T): Signal<T | undefined> {
return new Signal(oldValue);
}
export class Signal<T = any> implements Dependency {
public readonly [ReactiveFlags.IS_REFERENCE] = true
// Dependency fields
subs: Link | undefined = undefined;
subsTail: Link | undefined = undefined;
constructor(
public currentValue: T
) { }
get(): T {
if (activeSub !== undefined) {
link(this, activeSub);
}
return this.currentValue;
}
set(value: T): void {
if (this.currentValue !== value) {
this.currentValue = value;
const subs = this.subs;
if (subs !== undefined) {
propagate(subs);
if (!batchDepth) {
processEffectNotifications();
}
}
}
}
value(): T {
return this.get();
}
peek(): T {
return this.currentValue;
}
}
export function computed<T>(getter: () => T): Computed<T> {
return new Computed<T>(getter);
}
export class Computed<T = any> implements Subscriber, Dependency {
readonly [ReactiveFlags.IS_REFERENCE] = true
currentValue: T | undefined = undefined;
// Dependency fields
subs: Link | undefined = undefined;
subsTail: Link | undefined = undefined;
// Subscriber fields
deps: Link | undefined = undefined;
depsTail: Link | undefined = undefined;
flags: SubscriberFlags = SubscriberFlags.Computed | SubscriberFlags.Dirty;
constructor(
public getter: () => T
) { }
get(): T {
const flags = this.flags;
if (flags & (SubscriberFlags.PendingComputed | SubscriberFlags.Dirty)) {
processComputedUpdate(this, flags);
}
if (activeSub !== undefined) {
link(this, activeSub);
}
return this.currentValue!;
}
update(): boolean {
const prevSub = activeSub;
activeSub = this;
startTracking(this);
try {
const oldValue = this.currentValue;
const newValue = this.getter();
if (oldValue !== newValue) {
this.currentValue = newValue;
return true;
}
return false;
} finally {
activeSub = prevSub;
endTracking(this);
}
}
peek(): T {
return this.currentValue!;
}
value(): Readonly<T> {
return this.get();
}
}
export function effect<T>(fn: () => T): Effect<T> {
const e = new Effect(fn);
e.run();
return e;
}
export class Effect<T = any> implements Subscriber {
readonly [ReactiveFlags.IS_REFERENCE] = true
// Subscriber fields
deps: Link | undefined = undefined;
depsTail: Link | undefined = undefined;
flags: SubscriberFlags = SubscriberFlags.Effect;
constructor(
public fn: () => T
) { }
notify(): void {
const flags = this.flags;
if (
flags & SubscriberFlags.Dirty
|| (flags & SubscriberFlags.PendingComputed && updateDirtyFlag(this, flags))
) {
this.run();
}
}
run(): T {
const prevSub = activeSub;
activeSub = this;
startTracking(this);
try {
return this.fn();
} finally {
activeSub = prevSub;
endTracking(this);
}
}
stop(): void {
startTracking(this);
endTracking(this);
}
}
export function batch<T>(fn: () => T): T {
startBatch();
try {
return fn();
} finally {
endBatch();
}
}
export function isSignal<T>(r: Signal<T> | unknown): r is Signal<T>
export function isSignal(r: any): r is Signal {
return r ? r[ReactiveFlags.IS_REFERENCE] === true : false
}
export type MaybeSignal<T = any> =
| T
| Signal<T>
export type MaybeSignalOrGetter<T = any> = MaybeSignal<T> | Computed<T> | (() => T)
export function unSignal<T>(signal: MaybeSignal<T> | Computed<T>): T {
return (isSignal(signal) ? signal.value : signal) as T;
}
export const isFunction = (val: unknown): val is Function =>
typeof val === 'function'
export function toValue<T>(source: MaybeSignalOrGetter<T>): T {
return isFunction(source) ? source() : unSignal(source)
}

@ -1,5 +1,4 @@
import { computed } from "./computed"; import { computed, Signal, signal } from "./core";
import { signal, Signal } from "./signal"
const proxyToSignals = new WeakMap(); const proxyToSignals = new WeakMap();
const objToProxy = new WeakMap(); const objToProxy = new WeakMap();
@ -99,7 +98,7 @@ const objectHandlers = {
if (!(val instanceof Signal)) throwOnMutation(); if (!(val instanceof Signal)) throwOnMutation();
const key = fullKey.replace(rg, ""); const key = fullKey.replace(rg, "");
signals.set(key, val); signals.set(key, val);
return Reflect.set(target, key, val.peek(), receiver); return Reflect.set(target, key, val(), receiver);
} else { } else {
let internal = val; let internal = val;
if (shouldProxy(val)) { if (shouldProxy(val)) {

@ -1,3 +1,2 @@
export * from "./computed"; export * from "./core";
export * from "./signal";
export * from "./deepSignal"; export * from "./deepSignal";

@ -1,26 +0,0 @@
import { Signal as AlienSignal } from 'alien-signals';
export function signal<T>(): Signal<T | undefined>;
export function signal<T>(oldValue: T): Signal<T>;
export function signal<T>(oldValue?: T): Signal<T | undefined> {
return new Signal(oldValue);
}
export class Signal<T = any> extends AlienSignal {
constructor(
currentValue: T
) {
super(currentValue);
}
get value(): T {
return this.get()
}
set value(value: T) {
this.set(value)
}
peek(): T {
return this.currentValue;
}
}

@ -11,13 +11,13 @@
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": false,
"noEmit": true, "noEmit": true,
/* Linting */ /* Linting */
"strict": true, "strict": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true "noFallthroughCasesInSwitch": true,
}, },
"include": [ "include": [
"src" "src"

@ -9,5 +9,6 @@ export const tsup: Options = {
splitting: true, splitting: true,
clean: true, clean: true,
shims: false, shims: false,
minify: false,
external: ['alien-signals'], external: ['alien-signals'],
} }

Loading…
Cancel
Save