signalium 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -3
- package/CHANGELOG.md +6 -0
- package/dist/cjs/react/provider.d.ts +2 -3
- package/dist/cjs/react/provider.d.ts.map +1 -1
- package/dist/cjs/react/provider.js +2 -2
- package/dist/cjs/react/provider.js.map +1 -1
- package/dist/esm/react/provider.d.ts +2 -3
- package/dist/esm/react/provider.d.ts.map +1 -1
- package/dist/esm/react/provider.js +3 -3
- package/dist/esm/react/provider.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/context.test.ts +48 -0
- package/src/react/__tests__/contexts.test.tsx +64 -1
- package/src/react/provider.tsx +4 -6
package/.turbo/turbo-build.log
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
|
2
|
-
> signalium@1.1.
|
2
|
+
> signalium@1.1.1 build
|
3
3
|
> npm run build:esm && npm run build:cjs
|
4
4
|
|
5
5
|
|
6
|
-
> signalium@1.1.
|
6
|
+
> signalium@1.1.1 build:esm
|
7
7
|
> tsc
|
8
8
|
|
9
9
|
|
10
|
-
> signalium@1.1.
|
10
|
+
> signalium@1.1.1 build:cjs
|
11
11
|
> tsc --module commonjs --outDir dist/cjs --moduleResolution node
|
12
12
|
|
package/CHANGELOG.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
import { ContextPair } from '../internals/contexts.js';
|
2
|
-
export declare function ContextProvider<C extends unknown[]>({ children, contexts, inherit,
|
2
|
+
export declare function ContextProvider<C extends unknown[]>({ children, contexts, inherit, }: {
|
3
3
|
children: React.ReactNode;
|
4
|
-
contexts
|
4
|
+
contexts?: [...ContextPair<C>] | [];
|
5
5
|
inherit?: boolean;
|
6
|
-
root?: boolean;
|
7
6
|
}): import("react/jsx-runtime").JSX.Element;
|
8
7
|
//# sourceMappingURL=provider.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAA2B,MAAM,0BAA0B,CAAC;AAE7F,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,EACnD,QAAQ,EACR,QAAa,EACb,OAAc,GACf,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,2CAKA"}
|
@@ -5,8 +5,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
6
6
|
const context_js_1 = require("./context.js");
|
7
7
|
const contexts_js_1 = require("../internals/contexts.js");
|
8
|
-
function ContextProvider({ children, contexts
|
9
|
-
const parentScope = (0, react_1.useContext)(context_js_1.ScopeContext);
|
8
|
+
function ContextProvider({ children, contexts = [], inherit = true, }) {
|
9
|
+
const parentScope = (0, react_1.useContext)(context_js_1.ScopeContext) ?? contexts_js_1.ROOT_SCOPE;
|
10
10
|
const scope = new contexts_js_1.SignalScope(contexts, inherit ? parentScope : undefined);
|
11
11
|
return (0, jsx_runtime_1.jsx)(context_js_1.ScopeContext.Provider, { value: scope, children: children });
|
12
12
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":";;AAIA,
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":";;AAIA,0CAaC;;AAjBD,iCAAmC;AACnC,6CAA4C;AAC5C,0DAA6F;AAE7F,SAAgB,eAAe,CAAsB,EACnD,QAAQ,EACR,QAAQ,GAAG,EAAE,EACb,OAAO,GAAG,IAAI,GAKf;IACC,MAAM,WAAW,GAAG,IAAA,kBAAU,EAAC,yBAAY,CAAC,IAAI,wBAAU,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,yBAAW,CAAC,QAA6C,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEhH,OAAO,uBAAC,yBAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAC;AACjF,CAAC"}
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import { ContextPair } from '../internals/contexts.js';
|
2
|
-
export declare function ContextProvider<C extends unknown[]>({ children, contexts, inherit,
|
2
|
+
export declare function ContextProvider<C extends unknown[]>({ children, contexts, inherit, }: {
|
3
3
|
children: React.ReactNode;
|
4
|
-
contexts
|
4
|
+
contexts?: [...ContextPair<C>] | [];
|
5
5
|
inherit?: boolean;
|
6
|
-
root?: boolean;
|
7
6
|
}): import("react/jsx-runtime").JSX.Element;
|
8
7
|
//# sourceMappingURL=provider.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAA2B,MAAM,0BAA0B,CAAC;AAE7F,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,EACnD,QAAQ,EACR,QAAa,EACb,OAAc,GACf,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,2CAKA"}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
2
|
import { useContext } from 'react';
|
3
3
|
import { ScopeContext } from './context.js';
|
4
|
-
import { SignalScope } from '../internals/contexts.js';
|
5
|
-
export function ContextProvider({ children, contexts
|
6
|
-
const parentScope = useContext(ScopeContext);
|
4
|
+
import { ROOT_SCOPE, SignalScope } from '../internals/contexts.js';
|
5
|
+
export function ContextProvider({ children, contexts = [], inherit = true, }) {
|
6
|
+
const parentScope = useContext(ScopeContext) ?? ROOT_SCOPE;
|
7
7
|
const scope = new SignalScope(contexts, inherit ? parentScope : undefined);
|
8
8
|
return _jsx(ScopeContext.Provider, { value: scope, children: children });
|
9
9
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA4B,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA4B,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE7F,MAAM,UAAU,eAAe,CAAsB,EACnD,QAAQ,EACR,QAAQ,GAAG,EAAE,EACb,OAAO,GAAG,IAAI,GAKf;IACC,MAAM,WAAW,GAAG,UAAU,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,QAA6C,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEhH,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAC;AACjF,CAAC"}
|
package/package.json
CHANGED
@@ -65,6 +65,54 @@ describe('contexts', () => {
|
|
65
65
|
expect(derived()).toBe('Hi, Everyone');
|
66
66
|
});
|
67
67
|
|
68
|
+
test('withContexts inherits from root scope', () => {
|
69
|
+
const defaultValue1 = state('default1');
|
70
|
+
const defaultValue2 = state('default2');
|
71
|
+
const ctx1 = createContext(defaultValue1);
|
72
|
+
const ctx2 = createContext(defaultValue2);
|
73
|
+
const rootOverride1 = state('root1');
|
74
|
+
const rootOverride2 = state('root2');
|
75
|
+
|
76
|
+
// Set root contexts
|
77
|
+
setRootContexts([
|
78
|
+
[ctx1, rootOverride1],
|
79
|
+
[ctx2, rootOverride2],
|
80
|
+
]);
|
81
|
+
|
82
|
+
// Create a reactive function that uses both contexts
|
83
|
+
const derived = reactive(() => `${useContext(ctx1).get()}-${useContext(ctx2).get()}`);
|
84
|
+
|
85
|
+
// Should inherit from root scope when no local overrides
|
86
|
+
const result1 = withContexts([], () => derived());
|
87
|
+
expect(result1).toBe('root1-root2');
|
88
|
+
|
89
|
+
// Should inherit from root scope for unoverridden contexts
|
90
|
+
const localOverride1 = state('local1');
|
91
|
+
const result2 = withContexts([[ctx1, localOverride1]], () => derived());
|
92
|
+
expect(result2).toBe('local1-root2');
|
93
|
+
|
94
|
+
// Should use local overrides when provided
|
95
|
+
const localOverride2 = state('local2');
|
96
|
+
const result3 = withContexts(
|
97
|
+
[
|
98
|
+
[ctx1, localOverride1],
|
99
|
+
[ctx2, localOverride2],
|
100
|
+
],
|
101
|
+
() => derived(),
|
102
|
+
);
|
103
|
+
expect(result3).toBe('local1-local2');
|
104
|
+
|
105
|
+
// Changes to root contexts should be reflected in inherited contexts
|
106
|
+
rootOverride1.set('updated-root1');
|
107
|
+
rootOverride2.set('updated-root2');
|
108
|
+
|
109
|
+
const result4 = withContexts([], () => derived());
|
110
|
+
expect(result4).toBe('updated-root1-updated-root2');
|
111
|
+
|
112
|
+
const result5 = withContexts([[ctx1, localOverride1]], () => derived());
|
113
|
+
expect(result5).toBe('local1-updated-root2');
|
114
|
+
});
|
115
|
+
|
68
116
|
test('async computed maintains context ownership across await boundaries', async () => {
|
69
117
|
const ctx = createContext('default');
|
70
118
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
2
2
|
import { render } from 'vitest-browser-react';
|
3
|
-
import { state, reactive, createContext, useContext } from '
|
3
|
+
import { state, reactive, createContext, useContext, setRootContexts } from '../../index.js';
|
4
4
|
import { ContextProvider, setupReact, useScope } from '../index.js';
|
5
5
|
import React, { useState } from 'react';
|
6
6
|
|
@@ -49,6 +49,69 @@ describe('React > contexts', () => {
|
|
49
49
|
await expect.element(getByText('Hey, World')).toBeInTheDocument();
|
50
50
|
});
|
51
51
|
|
52
|
+
test('provider inherits from root scope', async () => {
|
53
|
+
const defaultValue1 = state('default1');
|
54
|
+
const defaultValue2 = state('default2');
|
55
|
+
const ctx1 = createContext(defaultValue1);
|
56
|
+
const ctx2 = createContext(defaultValue2);
|
57
|
+
const rootOverride1 = state('root1');
|
58
|
+
const rootOverride2 = state('root2');
|
59
|
+
|
60
|
+
// Set root contexts
|
61
|
+
setRootContexts([
|
62
|
+
[ctx1, rootOverride1],
|
63
|
+
[ctx2, rootOverride2],
|
64
|
+
]);
|
65
|
+
|
66
|
+
// Component that uses both contexts
|
67
|
+
function Component({ testId }: { testId: string }): React.ReactNode {
|
68
|
+
const value1 = useContext(ctx1);
|
69
|
+
const value2 = useContext(ctx2);
|
70
|
+
const derived = reactive(() => `${value1.get()}-${value2.get()}`);
|
71
|
+
return <div data-testid={testId}>{derived()}</div>;
|
72
|
+
}
|
73
|
+
const localOverride1 = state('local1');
|
74
|
+
const localOverride2 = state('local2');
|
75
|
+
|
76
|
+
// Should inherit from root scope when no local overrides
|
77
|
+
const { getByTestId } = render(
|
78
|
+
<>
|
79
|
+
<ContextProvider contexts={[]}>
|
80
|
+
<Component testId="result" />
|
81
|
+
</ContextProvider>
|
82
|
+
<ContextProvider contexts={[[ctx1, localOverride1]]}>
|
83
|
+
<Component testId="result2" />
|
84
|
+
</ContextProvider>
|
85
|
+
<ContextProvider
|
86
|
+
contexts={[
|
87
|
+
[ctx1, localOverride1],
|
88
|
+
[ctx2, localOverride2],
|
89
|
+
]}
|
90
|
+
>
|
91
|
+
<Component testId="result3" />
|
92
|
+
</ContextProvider>
|
93
|
+
</>,
|
94
|
+
);
|
95
|
+
|
96
|
+
await expect.element(getByTestId('result')).toHaveTextContent('root1-root2');
|
97
|
+
|
98
|
+
// Should inherit from root scope for unoverridden contexts
|
99
|
+
await expect.element(getByTestId('result2')).toHaveTextContent('local1-root2');
|
100
|
+
|
101
|
+
// Should use local overrides when provided
|
102
|
+
await expect.element(getByTestId('result3')).toHaveTextContent('local1-local2');
|
103
|
+
|
104
|
+
// Changes to root contexts should be reflected in inherited contexts
|
105
|
+
rootOverride1.set('updated-root1');
|
106
|
+
rootOverride2.set('updated-root2');
|
107
|
+
|
108
|
+
await expect.element(getByTestId('result')).toHaveTextContent('updated-root1-updated-root2');
|
109
|
+
|
110
|
+
// Local overrides should remain unaffected by root context changes
|
111
|
+
await expect.element(getByTestId('result2')).toHaveTextContent('local1-updated-root2');
|
112
|
+
await expect.element(getByTestId('result3')).toHaveTextContent('local1-local2');
|
113
|
+
});
|
114
|
+
|
52
115
|
test('useContext works inside computed value passed via context provider', async () => {
|
53
116
|
const value = state('Hello');
|
54
117
|
const override = state('Hey');
|
package/src/react/provider.tsx
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
import { useContext } from 'react';
|
2
2
|
import { ScopeContext } from './context.js';
|
3
|
-
import { ContextImpl, ContextPair, SignalScope } from '../internals/contexts.js';
|
3
|
+
import { ContextImpl, ContextPair, ROOT_SCOPE, SignalScope } from '../internals/contexts.js';
|
4
4
|
|
5
5
|
export function ContextProvider<C extends unknown[]>({
|
6
6
|
children,
|
7
|
-
contexts,
|
7
|
+
contexts = [],
|
8
8
|
inherit = true,
|
9
|
-
root = false,
|
10
9
|
}: {
|
11
10
|
children: React.ReactNode;
|
12
|
-
contexts
|
11
|
+
contexts?: [...ContextPair<C>] | [];
|
13
12
|
inherit?: boolean;
|
14
|
-
root?: boolean;
|
15
13
|
}) {
|
16
|
-
const parentScope = useContext(ScopeContext);
|
14
|
+
const parentScope = useContext(ScopeContext) ?? ROOT_SCOPE;
|
17
15
|
const scope = new SignalScope(contexts as [ContextImpl<unknown>, unknown][], inherit ? parentScope : undefined);
|
18
16
|
|
19
17
|
return <ScopeContext.Provider value={scope}>{children}</ScopeContext.Provider>;
|