CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes45downloads
README.md199 linesDownload Raw Back to alien-signals
1<p align="center">2	<img src="assets/logo.png" width="250"><br>3<p>4 5<p align="center">6	<a href="https://npmjs.com/package/alien-signals"><img src="https://badgen.net/npm/v/alien-signals" alt="npm package"></a>7</p>8 9<h3 align="center">10    <p>[<a href="https://github.com/YanqingXu/alien-signals-in-lua">Alien Signals in Lua</a>]</p>11    <p>[<a href="https://github.com/medz/alien-signals-dart">Alien Signals in Dart</a>]</p>12    <p>[<a href="https://github.com/Rajaniraiyn/react-alien-signals">React Binding</a>]</p>13</h3>14 15# alien-signals16 17The goal of `alien-signals` is to create a ~~push-pull~~ [push-pull-push model](https://github.com/stackblitz/alien-signals/pull/19) based signal library with the lowest overhead.18 19We have set the following constraints in scheduling logic:20 211. No dynamic object fields222. No use of Array/Set/Map233. No recursion calls244. Class properties must be fewer than 10 (https://v8.dev/blog/fast-properties)25 26Experimental results have shown that with these constraints, it is possible to achieve excellent performance for a Signal library without using sophisticated scheduling strategies. The overall performance of `alien-signals` is approximately 400% that of Vue 3.4's reactivity system.27 28For more detailed performance comparisons, please visit: https://github.com/transitive-bullshit/js-reactivity-benchmark29 30## Motivation31 32To achieve high-performance code generation in https://github.com/vuejs/language-tools, I needed to write some on-demand computed logic using Signals, but I couldn't find a low-cost Signal library that satisfied me.33 34In the past, I accumulated some knowledge of reactivity systems in https://github.com/vuejs/core/pull/5912, so I attempted to develop `alien-signals` with the goal of creating a Signal library with minimal memory usage and excellent performance.35 36Since Vue 3.5 switched to a Pull reactivity system in https://github.com/vuejs/core/pull/10397, I continued to research the Push-Pull reactivity system here. It is worth mentioning that I was inspired by the doubly-linked concept, but `alien-signals` does not use a similar implementation.37 38## Adoptions39 40- Used in Vue language tools (https://github.com/vuejs/language-tools) for virtual code generation.41 42- The core reactivity system code was ported to Vue 3.6 and later. (https://github.com/vuejs/core/pull/12349)43 44## Usage45 46### Basic47 48```ts49import { signal, computed, effect } from 'alien-signals';50 51const count = signal(1);52const doubleCount = computed(() => count.get() * 2);53 54effect(() => {55  console.log(`Count is: ${count.get()}`);56}); // Console: Count is: 157 58console.log(doubleCount.get()); // 259 60count.set(2); // Console: Count is: 261 62console.log(doubleCount.get()); // 463```64 65### Effect Scope66 67```ts68import { signal, effectScope } from 'alien-signals';69 70const count = signal(1);71const scope = effectScope();72 73scope.run(() => {74  effect(() => {75    console.log(`Count in scope: ${count.get()}`);76  }); // Console: Count in scope: 177 78  count.set(2); // Console: Count in scope: 279});80 81scope.stop();82 83count.set(3); // No console output84```85 86## About `propagate` and `checkDirty` functions87 88In order to eliminate recursive calls and improve performance, we record the last link node of the previous loop in `propagate` and `checkDirty` functions, and implement the rollback logic to return to this node.89 90This results in code that is difficult to understand, and you don't necessarily get the same performance improvements in other languages, so we record the original implementation without eliminating recursive calls here for reference.91 92#### `propagate`93 94```ts95export function propagate(link: Link, targetFlag: SubscriberFlags = SubscriberFlags.Dirty): void {96	do {97		const sub = link.sub;98		const subFlags = sub.flags;99 100		if (101			(102				!(subFlags & (SubscriberFlags.Tracking | SubscriberFlags.Recursed | SubscriberFlags.InnerEffectsPending | SubscriberFlags.ToCheckDirty | SubscriberFlags.Dirty))103				&& (sub.flags = subFlags | targetFlag, true)104			)105			|| (106				(subFlags & (SubscriberFlags.Tracking | SubscriberFlags.Recursed)) === SubscriberFlags.Recursed107				&& (sub.flags = (subFlags & ~SubscriberFlags.Recursed) | targetFlag, true)108			)109			|| (110				!(subFlags & (SubscriberFlags.InnerEffectsPending | SubscriberFlags.ToCheckDirty | SubscriberFlags.Dirty))111				&& isValidLink(link, sub)112				&& (113					sub.flags = subFlags | SubscriberFlags.Recursed | targetFlag,114					(sub as Dependency).subs !== undefined115				)116			)117		) {118			const subSubs = (sub as Dependency).subs;119			if (subSubs !== undefined) {120				propagate(121					subSubs,122					'notify' in sub123						? SubscriberFlags.InnerEffectsPending124						: SubscriberFlags.ToCheckDirty125				);126			} else if ('notify' in sub) {127				if (queuedEffectsTail !== undefined) {128					queuedEffectsTail.nextNotify = sub;129				} else {130					queuedEffects = sub;131				}132				queuedEffectsTail = sub;133			}134		} else if (135			!(subFlags & (SubscriberFlags.Tracking | targetFlag))136			|| (137				!(subFlags & targetFlag)138				&& (subFlags & (SubscriberFlags.InnerEffectsPending | SubscriberFlags.ToCheckDirty | SubscriberFlags.Dirty))139				&& isValidLink(link, sub)140			)141		) {142			sub.flags = subFlags | targetFlag;143		}144 145		link = link.nextSub!;146	} while (link !== undefined);147 148	if (targetFlag === SubscriberFlags.Dirty && !batchDepth) {149		drainQueuedEffects();150	}151}152```153 154#### `checkDirty`155 156```ts157export function checkDirty(link: Link): boolean {158	do {159		const dep = link.dep;160		if ('update' in dep) {161			const depFlags = dep.flags;162			if (depFlags & SubscriberFlags.Dirty) {163				if (dep.update()) {164					const subs = dep.subs!;165					if (subs.nextSub !== undefined) {166						shallowPropagate(subs);167					}168					return true;169				}170			} else if (depFlags & SubscriberFlags.ToCheckDirty) {171				if (checkDirty(dep.deps!)) {172					if (dep.update()) {173						const subs = dep.subs!;174						if (subs.nextSub !== undefined) {175							shallowPropagate(subs);176						}177						return true;178					}179				} else {180					dep.flags = depFlags & ~SubscriberFlags.ToCheckDirty;181				}182			}183		}184		link = link.nextDep!;185	} while (link !== undefined);186 187	return false;188}189```190 191## Roadmap192 193| Version | Savings                                                                                       |194|---------|-----------------------------------------------------------------------------------------------|195| 0.3     | Satisfy all 4 constraints                                                                     |196| 0.2     | Correctly schedule computed side effects                                                      |197| 0.1     | Correctly schedule inner effect callbacks                                                     |198| 0.0     | Add APIs: `signal()`, `computed()`, `effect()`, `effectScope()`, `startBatch()`, `endBatch()` |199 
basant307/AI_Governance_Project · CoolFace