Skip to content

Commit 864ac34

Browse files
authored
Merge pull request #7503 from QwikDev/v2-split-signals
chore: split and cleanup signals files
2 parents df664b7 + 4cffed7 commit 864ac34

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+976
-865
lines changed

packages/docs/src/routes/api/qwik/api.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@
335335
],
336336
"kind": "Interface",
337337
"content": "A computed signal is a signal which is calculated from other signals. When the signals change, the computed signal is recalculated, and if the result changed, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered.\n\n\n```typescript\nexport interface ComputedSignal<T> extends ReadonlySignal<T> \n```\n**Extends:** [ReadonlySignal](#readonlysignal)<!-- -->&lt;T&gt;\n\n\n<table><thead><tr><th>\n\nMethod\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[force()](#computedsignal-force)\n\n\n</td><td>\n\nUse this to force recalculation and running subscribers, for example when the calculated value mutates but remains the same object. Useful for third-party libraries.\n\n\n</td></tr>\n</tbody></table>",
338-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts",
338+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts",
339339
"mdFile": "core.computedsignal.md"
340340
},
341341
{
@@ -391,7 +391,7 @@
391391
],
392392
"kind": "Function",
393393
"content": "Create a computed signal which is calculated from the given QRL. A computed signal is a signal which is calculated from other signals. When the signals change, the computed signal is recalculated.\n\nThe QRL must be a function which returns the value of the signal. The function must not have side effects, and it must be synchronous.\n\nIf you need the function to be async, use `useSignal` and `useTask$` instead.\n\n\n```typescript\ncreateComputed$: <T>(qrl: () => T) => T extends Promise<any> ? never : ComputedSignal<T>\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nqrl\n\n\n</td><td>\n\n() =&gt; T\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nT extends Promise&lt;any&gt; ? never : [ComputedSignal](#computedsignal)<!-- -->&lt;T&gt;",
394-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts",
394+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts",
395395
"mdFile": "core.createcomputed_.md"
396396
},
397397
{
@@ -419,7 +419,7 @@
419419
],
420420
"kind": "Function",
421421
"content": "Create a signal that holds a custom serializable value. See [useSerializer$](#useserializer_) for more details.\n\n\n```typescript\ncreateSerializer$: <T, S>(arg: SerializerArg<T, S>) => T extends Promise<any> ? never : SerializerSignal<T>\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\narg\n\n\n</td><td>\n\nSerializerArg&lt;T, S&gt;\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nT extends Promise&lt;any&gt; ? never : SerializerSignal&lt;T&gt;",
422-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts",
422+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts",
423423
"mdFile": "core.createserializer_.md"
424424
},
425425
{
@@ -433,7 +433,7 @@
433433
],
434434
"kind": "Variable",
435435
"content": "Creates a Signal with the given value. If no value is given, the signal is created with `undefined`<!-- -->.\n\n\n```typescript\ncreateSignal: {\n <T>(): Signal<T | undefined>;\n <T>(value: T): Signal<T>;\n}\n```",
436-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts",
436+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts",
437437
"mdFile": "core.createsignal.md"
438438
},
439439
{
@@ -731,7 +731,7 @@
731731
],
732732
"kind": "Function",
733733
"content": "```typescript\nisSignal: (value: any) => value is Signal<unknown>\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nvalue\n\n\n</td><td>\n\nany\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nvalue is [Signal](#signal)<!-- -->&lt;unknown&gt;",
734-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.ts",
734+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/utils.ts",
735735
"mdFile": "core.issignal.md"
736736
},
737737
{
@@ -1543,7 +1543,7 @@
15431543
],
15441544
"kind": "Interface",
15451545
"content": "```typescript\nexport interface ReadonlySignal<T = unknown> \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[value](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\nT\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
1546-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts",
1546+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts",
15471547
"mdFile": "core.readonlysignal.md"
15481548
},
15491549
{
@@ -1781,7 +1781,7 @@
17811781
],
17821782
"kind": "Interface",
17831783
"content": "A signal is a reactive value which can be read and written. When the signal is written, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered.\n\nFurthermore, when a signal value is passed as a prop to a component, the optimizer will automatically forward the signal. This means that `return <div title={signal.value}>hi</div>` will update the `title` attribute when the signal changes without having to re-render the component.\n\n\n```typescript\nexport interface Signal<T = any> extends ReadonlySignal<T> \n```\n**Extends:** [ReadonlySignal](#readonlysignal)<!-- -->&lt;T&gt;\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[value](#)\n\n\n</td><td>\n\n\n</td><td>\n\nT\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
1784-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts",
1784+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts",
17851785
"mdFile": "core.signal.md"
17861786
},
17871787
{
@@ -2089,7 +2089,7 @@
20892089
],
20902090
"kind": "Function",
20912091
"content": "Get the original object that was wrapped by the store. Useful if you want to clone a store (structuredClone, IndexedDB,...)\n\n\n```typescript\nunwrapStore: <T>(value: T) => T\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nvalue\n\n\n</td><td>\n\nT\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nT",
2092-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/store.ts",
2092+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/impl/store.ts",
20932093
"mdFile": "core.unwrapstore.md"
20942094
},
20952095
{

packages/docs/src/routes/api/qwik/index.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ Use this to force recalculation and running subscribers, for example when the ca
383383
</td></tr>
384384
</tbody></table>
385385
386-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts)
386+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts)
387387
388388
## ContextId
389389
@@ -706,7 +706,7 @@ qrl
706706
707707
T extends Promise&lt;any&gt; ? never : [ComputedSignal](#computedsignal)&lt;T&gt;
708708
709-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts)
709+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts)
710710
711711
## createContextId
712712
@@ -826,7 +826,7 @@ SerializerArg&lt;T, S&gt;
826826

827827
T extends Promise&lt;any&gt; ? never : SerializerSignal&lt;T&gt;
828828

829-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts)
829+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts)
830830

831831
## createSignal
832832

@@ -839,7 +839,7 @@ createSignal: {
839839
}
840840
```
841841
842-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts)
842+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts)
843843
844844
## CSSProperties
845845
@@ -1456,7 +1456,7 @@ any
14561456
14571457
value is [Signal](#signal)&lt;unknown&gt;
14581458
1459-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.ts)
1459+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/utils.ts)
14601460
14611461
## jsx
14621462
@@ -2906,7 +2906,7 @@ T
29062906
</td></tr>
29072907
</tbody></table>
29082908
2909-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts)
2909+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts)
29102910
29112911
## render
29122912
@@ -3761,7 +3761,7 @@ T
37613761
</td></tr>
37623762
</tbody></table>
37633763
3764-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts)
3764+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/signal.public.ts)
37653765
37663766
## SkipRender
37673767
@@ -8415,7 +8415,7 @@ T
84158415
84168416
T
84178417
8418-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/store.ts)
8418+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/reactive-primitives/impl/store.ts)
84198419
84208420
## useComputed$
84218421

packages/qwik/src/core/client/vnode-diff.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ import {
9191
import { mapApp_findIndx } from './util-mapArray';
9292
import { mapArray_set } from './util-mapArray';
9393
import { getNewElementNamespaceData } from './vnode-namespace';
94-
import { WrappedSignal, EffectProperty, isSignal, SubscriptionData } from '../signal/signal';
95-
import type { Signal } from '../signal/signal.public';
94+
import { isSignal } from '../reactive-primitives/utils';
95+
import type { Signal } from '../reactive-primitives/signal.public';
9696
import { executeComponent } from '../shared/component-execution';
9797
import { isSlotProp } from '../shared/utils/prop';
9898
import { escapeHTML } from '../shared/utils/character-escaping';
99-
import { clearAllEffects } from '../signal/signal-cleanup';
99+
import { clearAllEffects } from '../reactive-primitives/cleanup';
100100
import { serializeAttribute } from '../shared/utils/styles';
101101
import { QError, qError } from '../shared/error/error';
102102
import { getFileLocationFromJsx } from '../shared/utils/jsx-filename';
103+
import { EffectProperty } from '../reactive-primitives/types';
104+
import { SubscriptionData } from '../reactive-primitives/subscription-data';
105+
import { WrappedSignalImpl } from '../reactive-primitives/impl/wrapped-signal-impl';
103106

104107
export const vnode_diff = (
105108
container: ClientContainer,
@@ -512,7 +515,7 @@ export const vnode_diff = (
512515
const constProps = jsxNode.constProps;
513516
if (constProps && typeof constProps == 'object' && 'name' in constProps) {
514517
const constValue = constProps.name;
515-
if (vHost && constValue instanceof WrappedSignal) {
518+
if (vHost && constValue instanceof WrappedSignalImpl) {
516519
return trackSignalAndAssignHost(constValue, vHost, EffectProperty.COMPONENT, container);
517520
}
518521
}

packages/qwik/src/core/client/vnode-diff.unit.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { describe, expect, it } from 'vitest';
44
import { vnode_applyJournal, vnode_getFirstChild, vnode_getNode } from './vnode';
55
import { vnode_diff } from './vnode-diff';
66
import type { QElement } from '../shared/types';
7-
import { createSignal } from '../signal/signal-api';
7+
import { createSignal } from '../reactive-primitives/signal-api';
88
import { QError, qError } from '../shared/error/error';
99

1010
describe('vNode-diff', () => {

packages/qwik/src/core/client/vnode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ import {
175175
vnode_getElementNamespaceFlags,
176176
} from './vnode-namespace';
177177
import { mergeMaps } from '../shared/utils/maps';
178-
import { _EFFECT_BACK_REF } from '../signal/flags';
178+
import { _EFFECT_BACK_REF } from '../reactive-primitives/types';
179179

180180
//////////////////////////////////////////////////////////////////////////////////////////////////////
181181

packages/qwik/src/core/core.api.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,6 @@ export { DomContainer as _DomContainer }
238238
// @internal (undocumented)
239239
export const _EFFECT_BACK_REF: unique symbol;
240240

241-
// @internal (undocumented)
242-
export class _EffectData {
243-
constructor(data: NodePropData);
244-
// Warning: (ae-forgotten-export) The symbol "NodePropData" needs to be exported by the entry point index.d.ts
245-
//
246-
// (undocumented)
247-
data: NodePropData;
248-
}
249-
250241
// @internal (undocumented)
251242
export type _ElementVNode = [
252243
_VNodeFlags.Element,
@@ -290,10 +281,10 @@ export type EventHandler<EV = Event, EL = Element> = {
290281
// @internal (undocumented)
291282
export const eventQrl: <T>(qrl: QRL<T>) => QRL<T>;
292283

293-
// Warning: (ae-forgotten-export) The symbol "WrappedSignal" needs to be exported by the entry point index.d.ts
284+
// Warning: (ae-forgotten-export) The symbol "WrappedSignalImpl" needs to be exported by the entry point index.d.ts
294285
//
295286
// @internal (undocumented)
296-
export const _fnSignal: <T extends (...args: any) => any>(fn: T, args: Parameters<T>, fnStr?: string) => WrappedSignal<any>;
287+
export const _fnSignal: <T extends (...args: any) => any>(fn: T, args: Parameters<T>, fnStr?: string) => WrappedSignalImpl<any>;
297288

298289
// @public (undocumented)
299290
export const Fragment: FunctionComponent<{
@@ -894,7 +885,7 @@ export abstract class _SharedContainer implements Container {
894885
// (undocumented)
895886
abstract setHostProp<T>(host: HostElement, name: string, value: T): void;
896887
// (undocumented)
897-
trackSignalValue<T>(signal: Signal, subscriber: HostElement, property: string, data: _EffectData): T;
888+
trackSignalValue<T>(signal: Signal, subscriber: HostElement, property: string, data: _SubscriptionData): T;
898889
}
899890

900891
// @public
@@ -1011,6 +1002,15 @@ export interface StreamWriter {
10111002
// @internal (undocumented)
10121003
export type _Stringifiable = string | boolean | number | null;
10131004

1005+
// @internal (undocumented)
1006+
export class _SubscriptionData {
1007+
constructor(data: NodePropData);
1008+
// Warning: (ae-forgotten-export) The symbol "NodePropData" needs to be exported by the entry point index.d.ts
1009+
//
1010+
// (undocumented)
1011+
data: NodePropData;
1012+
}
1013+
10141014
// Warning: (ae-forgotten-export) The symbol "AriaAttributes" needs to be exported by the entry point index.d.ts
10151015
//
10161016
// @public

packages/qwik/src/core/debug.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { isQrl } from '../server/prefetch-strategy';
22
import { isJSXNode } from './shared/jsx/jsx-runtime';
33
import { isTask } from './use/use-task';
44
import { vnode_getProp, vnode_isVNode } from './client/vnode';
5-
import { ComputedSignalImpl, WrappedSignal, isSignal } from './signal/signal';
6-
import { isStore } from './signal/store';
5+
import { isSignal } from './reactive-primitives/utils';
6+
import { isStore } from './reactive-primitives/impl/store';
77
import { DEBUG_TYPE } from './shared/types';
8+
import { ComputedSignalImpl } from './reactive-primitives/impl/computed-signal-impl';
9+
import { WrappedSignalImpl } from './reactive-primitives/impl/wrapped-signal-impl';
810

911
const stringifyPath: any[] = [];
1012
export function qwikDebugToString(value: any): any {
@@ -36,7 +38,7 @@ export function qwikDebugToString(value: any): any {
3638
return value.map(qwikDebugToString);
3739
}
3840
} else if (isSignal(value)) {
39-
if (value instanceof WrappedSignal) {
41+
if (value instanceof WrappedSignalImpl) {
4042
return 'WrappedSignal';
4143
} else if (value instanceof ComputedSignalImpl) {
4244
return 'ComputedSignal';

packages/qwik/src/core/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,19 @@ export { useVisibleTask$ } from './use/use-visible-task-dollar';
133133
export { useComputed$ } from './use/use-computed';
134134
export { useErrorBoundary } from './use/use-error-boundary';
135135
export type { ErrorBoundaryStore } from './shared/error/error-handling';
136-
export { type ReadonlySignal, type Signal, type ComputedSignal } from './signal/signal.public';
136+
export {
137+
type ReadonlySignal,
138+
type Signal,
139+
type ComputedSignal,
140+
} from './reactive-primitives/signal.public';
137141
export {
138142
isSignal,
139143
createSignal,
140144
createComputedQrl,
141145
createComputed$,
142146
createSerializerQrl,
143147
createSerializer$,
144-
} from './signal/signal.public';
145-
export { SubscriptionData as _EffectData } from './signal/signal';
148+
} from './reactive-primitives/signal.public';
146149

147150
//////////////////////////////////////////////////////////////////////////////////////////
148151
// Developer Low-Level API

packages/qwik/src/core/internal.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export { _walkJSX } from './ssr/ssr-render-jsx';
33
export { _SharedContainer } from './shared/shared-container';
44
export { queueQRL as _run } from './client/queue-qrl';
55
export { scheduleTask as _task } from './use/use-task';
6-
export { _wrapSignal, _wrapProp, _wrapStore } from './signal/signal-utils';
6+
export { _wrapSignal, _wrapProp, _wrapStore } from './reactive-primitives/internal-api';
77
export { _restProps } from './shared/utils/prop';
88
export { _IMMUTABLE } from './shared/utils/constants';
99
export { _CONST_PROPS, _VAR_PROPS } from './shared/utils/constants';
@@ -37,4 +37,5 @@ export {
3737
export { EMPTY_ARRAY as _EMPTY_ARRAY } from './shared/utils/flyweight';
3838
export { _serialize, _deserialize } from './shared/shared-serialization';
3939
export { _jsxQ, _jsxC, _jsxS } from './shared/jsx/jsx-runtime';
40-
export { _EFFECT_BACK_REF } from './signal/flags';
40+
export { _EFFECT_BACK_REF } from './reactive-primitives/types';
41+
export { SubscriptionData as _SubscriptionData } from './reactive-primitives/subscription-data';

packages/qwik/src/core/signal/signal-cleanup.ts renamed to packages/qwik/src/core/reactive-primitives/cleanup.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
import { ensureMaterialized, vnode_isElementVNode, vnode_isVNode } from '../client/vnode';
2+
import type { Container } from '../shared/types';
3+
import { SignalImpl } from './impl/signal-impl';
4+
import { WrappedSignalImpl } from './impl/wrapped-signal-impl';
5+
import { StoreHandler, getStoreHandler } from './impl/store';
16
import {
27
EffectSubscriptionProp,
3-
WrappedSignal,
4-
type EffectSubscription,
5-
SignalImpl,
6-
type EffectProperty,
8+
_EFFECT_BACK_REF,
79
type Consumer,
8-
} from './signal';
9-
import { StoreHandler, getStoreHandler } from './store';
10-
import type { Container } from '../shared/types';
11-
import { ensureMaterialized, vnode_isElementVNode, vnode_isVNode } from '../client/vnode';
12-
import { _EFFECT_BACK_REF } from './flags';
10+
type EffectProperty,
11+
type EffectSubscription,
12+
} from './types';
1313

1414
/** Class for back reference to the EffectSubscription */
1515
export abstract class BackRef {
@@ -47,7 +47,7 @@ function clearSignal(container: Container, producer: SignalImpl, effect: EffectS
4747
effects.delete(effect);
4848
}
4949

50-
if (producer instanceof WrappedSignal) {
50+
if (producer instanceof WrappedSignalImpl) {
5151
producer.$hostElement$ = null;
5252
clearAllEffects(container, producer);
5353
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Signals
2+
3+
Signals come in two types:
4+
5+
1. `Signal` - A storage of data
6+
2. `ComputedSignal` - A signal which is computed from other signals.
7+
8+
## Why is `ComputedSignal` different?
9+
10+
- It needs to store a function which needs to re-run.
11+
- It is `Readonly` because it is computed.

0 commit comments

Comments
 (0)