@webiny/react-composition 0.0.0-unstable.ecd8734205 → 0.0.0-unstable.f6dc066313

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/decorators.js ADDED
@@ -0,0 +1,71 @@
1
+ import React from "react";
2
+ import { Compose } from "./Compose.js";
3
+ export function createConditionalDecorator(shouldDecorate, decorator, decoratorProps) {
4
+ return Original => {
5
+ const DecoratedComponent = /*#__PURE__*/React.memo(decorator(Original));
6
+ DecoratedComponent.displayName = Original.displayName;
7
+ return function ShouldDecorate(props) {
8
+ if (shouldDecorate(decoratorProps, props)) {
9
+ // @ts-expect-error
10
+ return /*#__PURE__*/React.createElement(DecoratedComponent, props);
11
+ }
12
+
13
+ // @ts-expect-error
14
+ return /*#__PURE__*/React.createElement(Original, props);
15
+ };
16
+ };
17
+ }
18
+ const memoizedComponent = decorator => {
19
+ return decoratee => {
20
+ return /*#__PURE__*/React.memo(decorator(decoratee));
21
+ };
22
+ };
23
+ export function createDecoratorFactory() {
24
+ return function from(decoratable, shouldDecorate) {
25
+ return function createDecorator(decorator) {
26
+ return function DecoratorPlugin(props) {
27
+ if (shouldDecorate) {
28
+ const componentDecorator = createConditionalDecorator(shouldDecorate, decorator, props);
29
+ return /*#__PURE__*/React.createElement(Compose, {
30
+ function: decoratable,
31
+ with: componentDecorator
32
+ });
33
+ }
34
+ return /*#__PURE__*/React.createElement(Compose, {
35
+ function: decoratable,
36
+ with: memoizedComponent(decorator)
37
+ });
38
+ };
39
+ };
40
+ };
41
+ }
42
+ export function createHookDecoratorFactory() {
43
+ return function from(decoratable) {
44
+ return function createDecorator(decorator) {
45
+ return function DecoratorPlugin() {
46
+ return /*#__PURE__*/React.createElement(Compose, {
47
+ function: decoratable,
48
+ with: decorator
49
+ });
50
+ };
51
+ };
52
+ };
53
+ }
54
+ export function withDecoratorFactory() {
55
+ return function WithDecorator(Component, shouldDecorate) {
56
+ const createDecorator = createDecoratorFactory()(Component, shouldDecorate);
57
+ return Object.assign(Component, {
58
+ createDecorator
59
+ });
60
+ };
61
+ }
62
+ export function withHookDecoratorFactory() {
63
+ return function WithHookDecorator(hook) {
64
+ const createDecorator = createHookDecoratorFactory()(hook);
65
+ return Object.assign(hook, {
66
+ createDecorator
67
+ });
68
+ };
69
+ }
70
+
71
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","Compose","createConditionalDecorator","shouldDecorate","decorator","decoratorProps","Original","DecoratedComponent","memo","displayName","ShouldDecorate","props","createElement","memoizedComponent","decoratee","createDecoratorFactory","from","decoratable","createDecorator","DecoratorPlugin","componentDecorator","function","with","createHookDecoratorFactory","withDecoratorFactory","WithDecorator","Component","Object","assign","withHookDecoratorFactory","WithHookDecorator","hook"],"sources":["decorators.tsx"],"sourcesContent":["import React from \"react\";\nimport { Compose } from \"~/Compose.js\";\nimport type { GetDecoratee, GetDecorateeParams } from \"~/createDecorator.js\";\nimport type {\n DecoratableComponent,\n GenericComponent,\n Decorator,\n GenericHook,\n DecoratableHook,\n ComponentDecorator\n} from \"~/types.js\";\n\nexport interface ShouldDecorate<TDecorator = any, TComponent = any> {\n (decoratorProps: TDecorator, componentProps: TComponent): boolean;\n}\n\nexport function createConditionalDecorator<TDecoratee extends GenericComponent>(\n shouldDecorate: ShouldDecorate,\n decorator: Decorator<TDecoratee>,\n decoratorProps: unknown\n): Decorator<TDecoratee> {\n return (Original => {\n const DecoratedComponent = React.memo(decorator(Original));\n DecoratedComponent.displayName = Original.displayName;\n\n return function ShouldDecorate(props: unknown) {\n if (shouldDecorate(decoratorProps, props)) {\n // @ts-expect-error\n return <DecoratedComponent {...props} />;\n }\n\n // @ts-expect-error\n return <Original {...props} />;\n };\n }) as Decorator<TDecoratee>;\n}\n\nconst memoizedComponent = <T extends GenericComponent>(decorator: Decorator<T>) => {\n return (decoratee: T) => {\n return React.memo(decorator(decoratee));\n };\n};\n\nexport function createDecoratorFactory<TDecorator>() {\n return function from<TDecoratable extends DecoratableComponent>(\n decoratable: TDecoratable,\n shouldDecorate?: ShouldDecorate<TDecorator, GetDecorateeParams<GetDecoratee<TDecoratable>>>\n ) {\n return function createDecorator(decorator: ComponentDecorator<GetDecoratee<TDecoratable>>) {\n return function DecoratorPlugin(props: TDecorator) {\n if (shouldDecorate) {\n const componentDecorator = createConditionalDecorator<GenericComponent>(\n shouldDecorate,\n decorator as unknown as Decorator<GenericComponent>,\n props\n );\n\n return <Compose function={decoratable} with={componentDecorator} />;\n }\n\n return (\n <Compose\n function={decoratable}\n with={memoizedComponent(\n decorator as unknown as Decorator<GenericComponent>\n )}\n />\n );\n };\n };\n };\n}\n\nexport function createHookDecoratorFactory() {\n return function from<TDecoratable extends DecoratableHook>(decoratable: TDecoratable) {\n return function createDecorator(decorator: Decorator<GetDecoratee<TDecoratable>>) {\n return function DecoratorPlugin() {\n return (\n <Compose\n function={decoratable}\n with={decorator as unknown as Decorator<GenericHook>}\n />\n );\n };\n };\n };\n}\n\nexport function withDecoratorFactory<TDecorator>() {\n return function WithDecorator<TDecoratable extends DecoratableComponent>(\n Component: TDecoratable,\n shouldDecorate?: ShouldDecorate<TDecorator, GetDecorateeParams<GetDecoratee<TDecoratable>>>\n ) {\n const createDecorator = createDecoratorFactory<TDecorator>()(Component, shouldDecorate);\n\n return Object.assign(Component, { createDecorator }) as TDecoratable & {\n createDecorator: typeof createDecorator;\n };\n };\n}\n\nexport function withHookDecoratorFactory() {\n return function WithHookDecorator<TDecoratable extends DecoratableHook>(hook: TDecoratable) {\n const createDecorator = createHookDecoratorFactory()(hook);\n\n return Object.assign(hook, { createDecorator }) as unknown as DecoratableHook<\n GenericHook<\n GetDecorateeParams<GetDecoratee<TDecoratable>>,\n ReturnType<GetDecoratee<TDecoratable>>\n >\n > & { createDecorator: typeof createDecorator };\n };\n}\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,OAAO;AAehB,OAAO,SAASC,0BAA0BA,CACtCC,cAA8B,EAC9BC,SAAgC,EAChCC,cAAuB,EACF;EACrB,OAAQC,QAAQ,IAAI;IAChB,MAAMC,kBAAkB,gBAAGP,KAAK,CAACQ,IAAI,CAACJ,SAAS,CAACE,QAAQ,CAAC,CAAC;IAC1DC,kBAAkB,CAACE,WAAW,GAAGH,QAAQ,CAACG,WAAW;IAErD,OAAO,SAASC,cAAcA,CAACC,KAAc,EAAE;MAC3C,IAAIR,cAAc,CAACE,cAAc,EAAEM,KAAK,CAAC,EAAE;QACvC;QACA,oBAAOX,KAAA,CAAAY,aAAA,CAACL,kBAAkB,EAAKI,KAAQ,CAAC;MAC5C;;MAEA;MACA,oBAAOX,KAAA,CAAAY,aAAA,CAACN,QAAQ,EAAKK,KAAQ,CAAC;IAClC,CAAC;EACL,CAAC;AACL;AAEA,MAAME,iBAAiB,GAAgCT,SAAuB,IAAK;EAC/E,OAAQU,SAAY,IAAK;IACrB,oBAAOd,KAAK,CAACQ,IAAI,CAACJ,SAAS,CAACU,SAAS,CAAC,CAAC;EAC3C,CAAC;AACL,CAAC;AAED,OAAO,SAASC,sBAAsBA,CAAA,EAAe;EACjD,OAAO,SAASC,IAAIA,CAChBC,WAAyB,EACzBd,cAA2F,EAC7F;IACE,OAAO,SAASe,eAAeA,CAACd,SAAyD,EAAE;MACvF,OAAO,SAASe,eAAeA,CAACR,KAAiB,EAAE;QAC/C,IAAIR,cAAc,EAAE;UAChB,MAAMiB,kBAAkB,GAAGlB,0BAA0B,CACjDC,cAAc,EACdC,SAAS,EACTO,KACJ,CAAC;UAED,oBAAOX,KAAA,CAAAY,aAAA,CAACX,OAAO;YAACoB,QAAQ,EAAEJ,WAAY;YAACK,IAAI,EAAEF;UAAmB,CAAE,CAAC;QACvE;QAEA,oBACIpB,KAAA,CAAAY,aAAA,CAACX,OAAO;UACJoB,QAAQ,EAAEJ,WAAY;UACtBK,IAAI,EAAET,iBAAiB,CACnBT,SACJ;QAAE,CACL,CAAC;MAEV,CAAC;IACL,CAAC;EACL,CAAC;AACL;AAEA,OAAO,SAASmB,0BAA0BA,CAAA,EAAG;EACzC,OAAO,SAASP,IAAIA,CAAuCC,WAAyB,EAAE;IAClF,OAAO,SAASC,eAAeA,CAACd,SAAgD,EAAE;MAC9E,OAAO,SAASe,eAAeA,CAAA,EAAG;QAC9B,oBACInB,KAAA,CAAAY,aAAA,CAACX,OAAO;UACJoB,QAAQ,EAAEJ,WAAY;UACtBK,IAAI,EAAElB;QAA+C,CACxD,CAAC;MAEV,CAAC;IACL,CAAC;EACL,CAAC;AACL;AAEA,OAAO,SAASoB,oBAAoBA,CAAA,EAAe;EAC/C,OAAO,SAASC,aAAaA,CACzBC,SAAuB,EACvBvB,cAA2F,EAC7F;IACE,MAAMe,eAAe,GAAGH,sBAAsB,CAAa,CAAC,CAACW,SAAS,EAAEvB,cAAc,CAAC;IAEvF,OAAOwB,MAAM,CAACC,MAAM,CAACF,SAAS,EAAE;MAAER;IAAgB,CAAC,CAAC;EAGxD,CAAC;AACL;AAEA,OAAO,SAASW,wBAAwBA,CAAA,EAAG;EACvC,OAAO,SAASC,iBAAiBA,CAAuCC,IAAkB,EAAE;IACxF,MAAMb,eAAe,GAAGK,0BAA0B,CAAC,CAAC,CAACQ,IAAI,CAAC;IAE1D,OAAOJ,MAAM,CAACC,MAAM,CAACG,IAAI,EAAE;MAAEb;IAAgB,CAAC,CAAC;EAMnD,CAAC;AACL","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ import type { ComponentType } from "react";
2
+ import type { Decorator, GenericComponent, GenericHook } from "../types.js";
3
+ type Listener = () => void;
4
+ export declare class CompositionStore {
5
+ private scopes;
6
+ private version;
7
+ private listeners;
8
+ register(component: ComponentType<unknown>, hocs: Decorator<GenericComponent | GenericHook>[], scope?: string, inherit?: boolean, silent?: boolean): () => void;
9
+ unregister(component: ComponentType<unknown>, hocs: Decorator<GenericComponent | GenericHook>[], scope?: string): void;
10
+ getComponent(component: ComponentType<unknown>, scope?: string[]): GenericComponent | GenericHook | undefined;
11
+ subscribe: (listener: Listener) => (() => void);
12
+ getSnapshot: () => number;
13
+ private notifyListeners;
14
+ }
15
+ export {};
@@ -0,0 +1,102 @@
1
+ import { compose } from "../Context.js";
2
+ export class CompositionStore {
3
+ scopes = new Map();
4
+ version = 0;
5
+ listeners = new Set();
6
+ register(component, hocs, scope = "*", inherit = false, silent = false) {
7
+ const scopeMap = this.scopes.get(scope) || new Map();
8
+ const recipe = scopeMap.get(component) || {
9
+ component: component,
10
+ hocs: []
11
+ };
12
+
13
+ // Idempotent: skip if all HOCs are already registered (handles StrictMode double-render).
14
+ const newHocs = hocs.filter(hoc => !recipe.hocs.includes(hoc));
15
+ if (newHocs.length === 0) {
16
+ return () => this.unregister(component, hocs, scope);
17
+ }
18
+ const existingHocs = [...recipe.hocs];
19
+ if (inherit && scope !== "*") {
20
+ const globalScope = this.scopes.get("*") || new Map();
21
+ const globalRecipe = globalScope.get(component) || {
22
+ component: component,
23
+ hocs: []
24
+ };
25
+ // Only prepend global HOCs that aren't already present.
26
+ const globalHocsToAdd = globalRecipe.hocs.filter(hoc => !existingHocs.includes(hoc));
27
+ existingHocs.unshift(...globalHocsToAdd);
28
+ }
29
+ const finalHocs = [...existingHocs, ...newHocs];
30
+ scopeMap.set(component, {
31
+ component: compose(...[...finalHocs].reverse())(component),
32
+ hocs: finalHocs
33
+ });
34
+ this.scopes.set(scope, scopeMap);
35
+
36
+ // Bump the version so useSyncExternalStore sees a new snapshot.
37
+ this.version++;
38
+
39
+ // When called during render (silent=true), don't notify listeners —
40
+ // that would trigger setState in other components mid-render.
41
+ // Components that render after this point will see the updated snapshot.
42
+ if (!silent) {
43
+ this.notifyListeners();
44
+ }
45
+ return () => this.unregister(component, hocs, scope);
46
+ }
47
+ unregister(component, hocs, scope = "*") {
48
+ const scopeMap = this.scopes.get(scope);
49
+ if (!scopeMap) {
50
+ return;
51
+ }
52
+ const recipe = scopeMap.get(component);
53
+ if (!recipe) {
54
+ return;
55
+ }
56
+ const newHocs = recipe.hocs.filter(hoc => !hocs.includes(hoc));
57
+ if (newHocs.length === recipe.hocs.length) {
58
+ // Nothing was removed.
59
+ return;
60
+ }
61
+ if (newHocs.length === 0) {
62
+ scopeMap.delete(component);
63
+ } else {
64
+ scopeMap.set(component, {
65
+ component: compose(...[...newHocs].reverse())(component),
66
+ hocs: newHocs
67
+ });
68
+ }
69
+ this.version++;
70
+ this.notifyListeners();
71
+ }
72
+ getComponent(component, scope = []) {
73
+ const scopesToResolve = ["*", ...scope].reverse();
74
+ for (const s of scopesToResolve) {
75
+ const scopeMap = this.scopes.get(s);
76
+ if (!scopeMap) {
77
+ continue;
78
+ }
79
+ const composed = scopeMap.get(component);
80
+ if (composed) {
81
+ return composed.component;
82
+ }
83
+ }
84
+ return undefined;
85
+ }
86
+ subscribe = listener => {
87
+ this.listeners.add(listener);
88
+ return () => {
89
+ this.listeners.delete(listener);
90
+ };
91
+ };
92
+ getSnapshot = () => {
93
+ return this.version;
94
+ };
95
+ notifyListeners() {
96
+ for (const listener of this.listeners) {
97
+ listener();
98
+ }
99
+ }
100
+ }
101
+
102
+ //# sourceMappingURL=CompositionStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["compose","CompositionStore","scopes","Map","version","listeners","Set","register","component","hocs","scope","inherit","silent","scopeMap","get","recipe","newHocs","filter","hoc","includes","length","unregister","existingHocs","globalScope","globalRecipe","globalHocsToAdd","unshift","finalHocs","set","reverse","notifyListeners","delete","getComponent","scopesToResolve","s","composed","undefined","subscribe","listener","add","getSnapshot"],"sources":["CompositionStore.ts"],"sourcesContent":["import type { ComponentType } from \"react\";\nimport { compose } from \"~/Context.js\";\nimport type { Decorator, GenericComponent, GenericHook } from \"~/types.js\";\n\ninterface ComposedComponent {\n component: GenericHook | GenericComponent;\n hocs: Decorator<GenericComponent | GenericHook>[];\n}\n\ntype ComposedComponents = Map<ComponentType<unknown>, ComposedComponent>;\ntype ComponentScopes = Map<string, ComposedComponents>;\n\ntype Listener = () => void;\n\nexport class CompositionStore {\n private scopes: ComponentScopes = new Map();\n private version = 0;\n private listeners = new Set<Listener>();\n\n register(\n component: ComponentType<unknown>,\n hocs: Decorator<GenericComponent | GenericHook>[],\n scope = \"*\",\n inherit = false,\n silent = false\n ): () => void {\n const scopeMap: ComposedComponents = this.scopes.get(scope) || new Map();\n const recipe = scopeMap.get(component) || {\n component: component as any,\n hocs: [] as Decorator<GenericComponent | GenericHook>[]\n };\n\n // Idempotent: skip if all HOCs are already registered (handles StrictMode double-render).\n const newHocs = hocs.filter(hoc => !recipe.hocs.includes(hoc));\n if (newHocs.length === 0) {\n return () => this.unregister(component, hocs, scope);\n }\n\n const existingHocs = [...recipe.hocs];\n if (inherit && scope !== \"*\") {\n const globalScope = this.scopes.get(\"*\") || new Map();\n const globalRecipe = globalScope.get(component) || {\n component: component as any,\n hocs: [] as Decorator<GenericComponent | GenericHook>[]\n };\n // Only prepend global HOCs that aren't already present.\n const globalHocsToAdd = globalRecipe.hocs.filter(\n (hoc: Decorator<GenericComponent | GenericHook>) => !existingHocs.includes(hoc)\n );\n existingHocs.unshift(...globalHocsToAdd);\n }\n\n const finalHocs = [...existingHocs, ...newHocs];\n\n scopeMap.set(component, {\n component: compose(...[...finalHocs].reverse())(component as any),\n hocs: finalHocs\n });\n\n this.scopes.set(scope, scopeMap);\n\n // Bump the version so useSyncExternalStore sees a new snapshot.\n this.version++;\n\n // When called during render (silent=true), don't notify listeners —\n // that would trigger setState in other components mid-render.\n // Components that render after this point will see the updated snapshot.\n if (!silent) {\n this.notifyListeners();\n }\n\n return () => this.unregister(component, hocs, scope);\n }\n\n unregister(\n component: ComponentType<unknown>,\n hocs: Decorator<GenericComponent | GenericHook>[],\n scope = \"*\"\n ): void {\n const scopeMap = this.scopes.get(scope);\n if (!scopeMap) {\n return;\n }\n\n const recipe = scopeMap.get(component);\n if (!recipe) {\n return;\n }\n\n const newHocs = recipe.hocs.filter(hoc => !hocs.includes(hoc));\n if (newHocs.length === recipe.hocs.length) {\n // Nothing was removed.\n return;\n }\n\n if (newHocs.length === 0) {\n scopeMap.delete(component);\n } else {\n scopeMap.set(component, {\n component: compose(...[...newHocs].reverse())(component as any),\n hocs: newHocs\n });\n }\n\n this.version++;\n this.notifyListeners();\n }\n\n getComponent(\n component: ComponentType<unknown>,\n scope: string[] = []\n ): GenericComponent | GenericHook | undefined {\n const scopesToResolve = [\"*\", ...scope].reverse();\n for (const s of scopesToResolve) {\n const scopeMap = this.scopes.get(s);\n if (!scopeMap) {\n continue;\n }\n const composed = scopeMap.get(component);\n if (composed) {\n return composed.component;\n }\n }\n return undefined;\n }\n\n subscribe = (listener: Listener): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): number => {\n return this.version;\n };\n\n private notifyListeners(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
package/index.d.ts CHANGED
@@ -1,4 +1,9 @@
1
- export * from "./Context";
2
- export * from "./Compose";
3
- export * from "./makeComposable";
4
- export * from "./createComponentPlugin";
1
+ export * from "./Context.js";
2
+ export * from "./Compose.js";
3
+ export * from "./makeComposable.js";
4
+ export * from "./makeDecoratable.js";
5
+ export * from "./createDecorator.js";
6
+ export * from "./decorators.js";
7
+ export * from "./CompositionScope.js";
8
+ export { CompositionStore } from "./domain/CompositionStore.js";
9
+ export type * from "./types.js";
package/index.js CHANGED
@@ -1,57 +1,10 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
-
7
- var _Context = require("./Context");
8
-
9
- Object.keys(_Context).forEach(function (key) {
10
- if (key === "default" || key === "__esModule") return;
11
- if (key in exports && exports[key] === _Context[key]) return;
12
- Object.defineProperty(exports, key, {
13
- enumerable: true,
14
- get: function get() {
15
- return _Context[key];
16
- }
17
- });
18
- });
19
-
20
- var _Compose = require("./Compose");
21
-
22
- Object.keys(_Compose).forEach(function (key) {
23
- if (key === "default" || key === "__esModule") return;
24
- if (key in exports && exports[key] === _Compose[key]) return;
25
- Object.defineProperty(exports, key, {
26
- enumerable: true,
27
- get: function get() {
28
- return _Compose[key];
29
- }
30
- });
31
- });
32
-
33
- var _makeComposable = require("./makeComposable");
34
-
35
- Object.keys(_makeComposable).forEach(function (key) {
36
- if (key === "default" || key === "__esModule") return;
37
- if (key in exports && exports[key] === _makeComposable[key]) return;
38
- Object.defineProperty(exports, key, {
39
- enumerable: true,
40
- get: function get() {
41
- return _makeComposable[key];
42
- }
43
- });
44
- });
45
-
46
- var _createComponentPlugin = require("./createComponentPlugin");
47
-
48
- Object.keys(_createComponentPlugin).forEach(function (key) {
49
- if (key === "default" || key === "__esModule") return;
50
- if (key in exports && exports[key] === _createComponentPlugin[key]) return;
51
- Object.defineProperty(exports, key, {
52
- enumerable: true,
53
- get: function get() {
54
- return _createComponentPlugin[key];
55
- }
56
- });
57
- });
1
+ export * from "./Context.js";
2
+ export * from "./Compose.js";
3
+ export * from "./makeComposable.js";
4
+ export * from "./makeDecoratable.js";
5
+ export * from "./createDecorator.js";
6
+ export * from "./decorators.js";
7
+ export * from "./CompositionScope.js";
8
+ export { CompositionStore } from "./domain/CompositionStore.js";
9
+
10
+ //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./Context\";\nexport * from \"./Compose\";\nexport * from \"./makeComposable\";\nexport * from \"./createComponentPlugin\";\n"],"mappings":";;;;;;AAAA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA"}
1
+ {"version":3,"names":["CompositionStore"],"sources":["index.ts"],"sourcesContent":["export * from \"./Context.js\";\nexport * from \"./Compose.js\";\nexport * from \"./makeComposable.js\";\nexport * from \"./makeDecoratable.js\";\nexport * from \"./createDecorator.js\";\nexport * from \"./decorators.js\";\nexport * from \"./CompositionScope.js\";\nexport { CompositionStore } from \"./domain/CompositionStore.js\";\nexport type * from \"./types.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,gBAAgB","ignoreList":[]}
@@ -1,3 +1,43 @@
1
- import React from "react";
2
- import { ComposableFC } from "./Compose";
3
- export declare function makeComposable<TProps>(name: string, Component?: React.FC<TProps>): ComposableFC<TProps>;
1
+ import type { GenericComponent } from "./types.js";
2
+ /**
3
+ * @deprecated Use `makeDecoratable` instead.
4
+ */
5
+ export declare function makeComposable<T extends GenericComponent>(name: string, Component?: T): (((() => null) | T) & {
6
+ original: (() => null) | T;
7
+ originalName: string;
8
+ displayName: string;
9
+ }) & {
10
+ original: ((() => null) | T) & {
11
+ original: (() => null) | T;
12
+ originalName: string;
13
+ displayName: string;
14
+ };
15
+ originalName: string;
16
+ displayName: string;
17
+ } & {
18
+ createDecorator: (decorator: import("~/types.js").ComponentDecorator<import("./createDecorator").GetDecoratee<(() => null) & {
19
+ original: (() => null) | T;
20
+ originalName: string;
21
+ displayName: string;
22
+ } & {
23
+ original: ((() => null) | T) & {
24
+ original: (() => null) | T;
25
+ originalName: string;
26
+ displayName: string;
27
+ };
28
+ originalName: string;
29
+ displayName: string;
30
+ }> | import("./createDecorator").GetDecoratee<T & {
31
+ original: (() => null) | T;
32
+ originalName: string;
33
+ displayName: string;
34
+ } & {
35
+ original: ((() => null) | T) & {
36
+ original: (() => null) | T;
37
+ originalName: string;
38
+ displayName: string;
39
+ };
40
+ originalName: string;
41
+ displayName: string;
42
+ }>>) => (props: unknown) => import("react").JSX.Element;
43
+ };
package/makeComposable.js CHANGED
@@ -1,72 +1,14 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
-
5
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
6
-
7
- Object.defineProperty(exports, "__esModule", {
8
- value: true
9
- });
10
- exports.makeComposable = makeComposable;
11
-
12
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
-
14
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
-
16
- var _react = _interopRequireWildcard(require("react"));
17
-
18
- var _lodash = _interopRequireDefault(require("lodash.debounce"));
19
-
20
- var _Context = require("./Context");
21
-
22
- var ComposableContext = /*#__PURE__*/(0, _react.createContext)([]);
1
+ import { createContext } from "react";
2
+ import { makeDecoratable } from "./makeDecoratable.js";
3
+ const ComposableContext = /*#__PURE__*/createContext([]);
23
4
  ComposableContext.displayName = "ComposableContext";
5
+ const nullRenderer = () => null;
24
6
 
25
- function useComposableParents() {
26
- var context = (0, _react.useContext)(ComposableContext);
27
-
28
- if (!context) {
29
- return [];
30
- }
31
-
32
- return context;
7
+ /**
8
+ * @deprecated Use `makeDecoratable` instead.
9
+ */
10
+ export function makeComposable(name, Component) {
11
+ return makeDecoratable(name, Component ?? nullRenderer);
33
12
  }
34
13
 
35
- var createEmptyRenderer = function createEmptyRenderer(name) {
36
- return (0, _defineProperty2.default)({}, name, function () {
37
- (0, _react.useEffect)(function () {
38
- // We need to debounce the log, as it sometimes only requires a single tick to get the new
39
- // composed component to render, and we don't want to scare developers for no reason.
40
- var debounced = (0, _lodash.default)(function () {
41
- console.info("<".concat(name, "/> is not implemented! To provide an implementation, use the <Compose/> component."));
42
- }, 100);
43
- return function () {
44
- debounced.cancel();
45
- };
46
- }, []);
47
- return null;
48
- })[name];
49
- };
50
-
51
- function makeComposable(name, Component) {
52
- if (!Component) {
53
- Component = createEmptyRenderer(name);
54
- }
55
-
56
- var Composable = function Composable(props) {
57
- var parents = useComposableParents();
58
- var ComposedComponent = (0, _Context.useComponent)(Component);
59
- var context = (0, _react.useMemo)(function () {
60
- return [].concat((0, _toConsumableArray2.default)(parents), [name]);
61
- }, [parents, name]);
62
- return /*#__PURE__*/_react.default.createElement(ComposableContext.Provider, {
63
- value: context
64
- }, /*#__PURE__*/_react.default.createElement(ComposedComponent, props, props.children));
65
- };
66
-
67
- Component.displayName = name;
68
- Composable.original = Component;
69
- Composable.originalName = name;
70
- Composable.displayName = "Composable<".concat(name, ">");
71
- return Composable;
72
- }
14
+ //# sourceMappingURL=makeComposable.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ComposableContext","createContext","displayName","useComposableParents","context","useContext","createEmptyRenderer","name","useEffect","debounced","debounce","console","info","cancel","makeComposable","Component","Composable","props","parents","ComposedComponent","useComponent","useMemo","children","original","originalName"],"sources":["makeComposable.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useMemo } from \"react\";\nimport debounce from \"lodash.debounce\";\nimport { ComposableFC } from \"./Compose\";\nimport { useComponent } from \"./Context\";\n\nconst ComposableContext = createContext<string[]>([]);\nComposableContext.displayName = \"ComposableContext\";\n\nfunction useComposableParents() {\n const context = useContext(ComposableContext);\n if (!context) {\n return [];\n }\n\n return context;\n}\n\nconst createEmptyRenderer = (name: string): React.FC => {\n return {\n [name]: function () {\n useEffect(() => {\n // We need to debounce the log, as it sometimes only requires a single tick to get the new\n // composed component to render, and we don't want to scare developers for no reason.\n const debounced = debounce(() => {\n console.info(\n `<${name}/> is not implemented! To provide an implementation, use the <Compose/> component.`\n );\n }, 100);\n\n return () => {\n debounced.cancel();\n };\n }, []);\n\n return null;\n }\n }[name];\n};\n\nexport function makeComposable<TProps>(name: string, Component?: React.FC<TProps>) {\n if (!Component) {\n Component = createEmptyRenderer(name);\n }\n\n const Composable: ComposableFC<TProps> = props => {\n const parents = useComposableParents();\n const ComposedComponent = useComponent(Component as React.FC<TProps>);\n\n const context = useMemo(() => [...parents, name], [parents, name]);\n\n return (\n <ComposableContext.Provider value={context}>\n <ComposedComponent {...props}>{props.children}</ComposedComponent>\n </ComposableContext.Provider>\n );\n };\n\n Component.displayName = name;\n\n Composable.original = Component;\n Composable.originalName = name;\n Composable.displayName = `Composable<${name}>`;\n\n return Composable;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA;;AACA;;AAEA;;AAEA,IAAMA,iBAAiB,gBAAG,IAAAC,oBAAA,EAAwB,EAAxB,CAA1B;AACAD,iBAAiB,CAACE,WAAlB,GAAgC,mBAAhC;;AAEA,SAASC,oBAAT,GAAgC;EAC5B,IAAMC,OAAO,GAAG,IAAAC,iBAAA,EAAWL,iBAAX,CAAhB;;EACA,IAAI,CAACI,OAAL,EAAc;IACV,OAAO,EAAP;EACH;;EAED,OAAOA,OAAP;AACH;;AAED,IAAME,mBAAmB,GAAG,SAAtBA,mBAAsB,CAACC,IAAD,EAA4B;EACpD,OAAO,kCACFA,IADE,EACK,YAAY;IAChB,IAAAC,gBAAA,EAAU,YAAM;MACZ;MACA;MACA,IAAMC,SAAS,GAAG,IAAAC,eAAA,EAAS,YAAM;QAC7BC,OAAO,CAACC,IAAR,YACQL,IADR;MAGH,CAJiB,EAIf,GAJe,CAAlB;MAMA,OAAO,YAAM;QACTE,SAAS,CAACI,MAAV;MACH,CAFD;IAGH,CAZD,EAYG,EAZH;IAcA,OAAO,IAAP;EACH,CAjBE,EAkBLN,IAlBK,CAAP;AAmBH,CApBD;;AAsBO,SAASO,cAAT,CAAgCP,IAAhC,EAA8CQ,SAA9C,EAA4E;EAC/E,IAAI,CAACA,SAAL,EAAgB;IACZA,SAAS,GAAGT,mBAAmB,CAACC,IAAD,CAA/B;EACH;;EAED,IAAMS,UAAgC,GAAG,SAAnCA,UAAmC,CAAAC,KAAK,EAAI;IAC9C,IAAMC,OAAO,GAAGf,oBAAoB,EAApC;IACA,IAAMgB,iBAAiB,GAAG,IAAAC,qBAAA,EAAaL,SAAb,CAA1B;IAEA,IAAMX,OAAO,GAAG,IAAAiB,cAAA,EAAQ;MAAA,kDAAUH,OAAV,IAAmBX,IAAnB;IAAA,CAAR,EAAkC,CAACW,OAAD,EAAUX,IAAV,CAAlC,CAAhB;IAEA,oBACI,6BAAC,iBAAD,CAAmB,QAAnB;MAA4B,KAAK,EAAEH;IAAnC,gBACI,6BAAC,iBAAD,EAAuBa,KAAvB,EAA+BA,KAAK,CAACK,QAArC,CADJ,CADJ;EAKH,CAXD;;EAaAP,SAAS,CAACb,WAAV,GAAwBK,IAAxB;EAEAS,UAAU,CAACO,QAAX,GAAsBR,SAAtB;EACAC,UAAU,CAACQ,YAAX,GAA0BjB,IAA1B;EACAS,UAAU,CAACd,WAAX,wBAAuCK,IAAvC;EAEA,OAAOS,UAAP;AACH"}
1
+ {"version":3,"names":["createContext","makeDecoratable","ComposableContext","displayName","nullRenderer","makeComposable","name","Component"],"sources":["makeComposable.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { GenericComponent } from \"~/types.js\";\nimport { makeDecoratable } from \"~/makeDecoratable.js\";\n\nconst ComposableContext = createContext<string[]>([]);\nComposableContext.displayName = \"ComposableContext\";\n\nconst nullRenderer = () => null;\n\n/**\n * @deprecated Use `makeDecoratable` instead.\n */\nexport function makeComposable<T extends GenericComponent>(name: string, Component?: T) {\n return makeDecoratable(name, Component ?? nullRenderer);\n}\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,OAAO;AAErC,SAASC,eAAe;AAExB,MAAMC,iBAAiB,gBAAGF,aAAa,CAAW,EAAE,CAAC;AACrDE,iBAAiB,CAACC,WAAW,GAAG,mBAAmB;AAEnD,MAAMC,YAAY,GAAGA,CAAA,KAAM,IAAI;;AAE/B;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAA6BC,IAAY,EAAEC,SAAa,EAAE;EACpF,OAAON,eAAe,CAACK,IAAI,EAAEC,SAAS,IAAIH,YAAY,CAAC;AAC3D","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import type { DecoratableComponent, DecoratableHook, GenericComponent, GenericHook } from "./types.js";
3
+ declare function makeDecoratableComponent<T extends GenericComponent>(name: string, Component?: T): T & {
4
+ original: T;
5
+ originalName: string;
6
+ displayName: string;
7
+ } & {
8
+ original: T & {
9
+ original: T;
10
+ originalName: string;
11
+ displayName: string;
12
+ };
13
+ originalName: string;
14
+ displayName: string;
15
+ } & {
16
+ createDecorator: (decorator: import("~/types.js").ComponentDecorator<import("./createDecorator.js").GetDecoratee<DecoratableComponent<T & {
17
+ original: T;
18
+ originalName: string;
19
+ displayName: string;
20
+ }>>>) => (props: unknown) => React.JSX.Element;
21
+ };
22
+ export declare function makeDecoratableHook<T extends GenericHook>(hook: T): GenericHook<import("./createDecorator.js").GetDecorateeParams<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>, ReturnType<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>> & {
23
+ original: GenericHook<import("./createDecorator.js").GetDecorateeParams<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>, ReturnType<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>>;
24
+ originalName: string;
25
+ } & {
26
+ createDecorator: (decorator: import("~/types.js").Decorator<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>) => () => React.JSX.Element;
27
+ };
28
+ export declare function createVoidComponent<T>(): (props: T) => JSX.Element | null;
29
+ export declare function makeDecoratable<T extends GenericHook>(hook: T): ReturnType<typeof makeDecoratableHook<T>>;
30
+ export declare function makeDecoratable<T extends GenericComponent>(name: string, Component: T): ReturnType<typeof makeDecoratableComponent<T>>;
31
+ export {};
@@ -0,0 +1,90 @@
1
+ import React, { createContext, useContext, useMemo } from "react";
2
+ import { useComponent } from "./Context.js";
3
+ import { withDecoratorFactory, withHookDecoratorFactory } from "./decorators.js";
4
+ class DecoratableErrorBoundary extends React.Component {
5
+ constructor(props) {
6
+ super(props);
7
+ this.state = {
8
+ hasError: false,
9
+ error: undefined
10
+ };
11
+ }
12
+ static getDerivedStateFromError(error) {
13
+ return {
14
+ hasError: true,
15
+ error
16
+ };
17
+ }
18
+ componentDidCatch(error, errorInfo) {
19
+ console.groupCollapsed(`%cCOMPONENT ERROR%c: "${this.props.name}" failed to render.`, "color:red", "color:default");
20
+ console.error(error, errorInfo);
21
+ console.groupEnd();
22
+ }
23
+ render() {
24
+ if (this.state.hasError) {
25
+ return /*#__PURE__*/React.createElement("div", {
26
+ style: {
27
+ padding: "8px 12px",
28
+ border: "1px solid #e53e3e",
29
+ borderRadius: 4,
30
+ background: "#fff5f5",
31
+ color: "#c53030",
32
+ fontSize: 13
33
+ }
34
+ }, /*#__PURE__*/React.createElement("strong", null, this.props.name), ": ", this.state.error?.message);
35
+ }
36
+ return this.props.children;
37
+ }
38
+ }
39
+ const ComposableContext = /*#__PURE__*/createContext([]);
40
+ ComposableContext.displayName = "ComposableContext";
41
+ function useComposableParents() {
42
+ const context = useContext(ComposableContext);
43
+ if (!context) {
44
+ return [];
45
+ }
46
+ return context;
47
+ }
48
+ const nullRenderer = () => null;
49
+ function makeDecoratableComponent(name, Component = nullRenderer) {
50
+ const Decoratable = props => {
51
+ const parents = useComposableParents();
52
+ const ComposedComponent = useComponent(Component);
53
+ const context = useMemo(() => [...parents, name], [parents, name]);
54
+ return /*#__PURE__*/React.createElement(ComposableContext.Provider, {
55
+ value: context
56
+ }, /*#__PURE__*/React.createElement(DecoratableErrorBoundary, {
57
+ name: name
58
+ }, /*#__PURE__*/React.createElement(ComposedComponent, props, props.children)));
59
+ };
60
+ const staticProps = {
61
+ original: Component,
62
+ originalName: name,
63
+ displayName: `Decoratable<${name}>`
64
+ };
65
+ return withDecoratorFactory()(Object.assign(Decoratable, staticProps));
66
+ }
67
+ export function makeDecoratableHook(hook) {
68
+ const decoratableHook = params => {
69
+ const composedHook = useComponent(hook);
70
+ return composedHook(params);
71
+ };
72
+ decoratableHook.original = hook;
73
+ return withHookDecoratorFactory()(decoratableHook);
74
+ }
75
+ export function createVoidComponent() {
76
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
77
+ return props => {
78
+ return null;
79
+ };
80
+ }
81
+ export function makeDecoratable(hookOrName, Component) {
82
+ if (Component) {
83
+ const component = makeDecoratableComponent(hookOrName, /*#__PURE__*/React.memo(Component));
84
+ component.original.displayName = hookOrName;
85
+ return component;
86
+ }
87
+ return makeDecoratableHook(hookOrName);
88
+ }
89
+
90
+ //# sourceMappingURL=makeDecoratable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","createContext","useContext","useMemo","useComponent","withDecoratorFactory","withHookDecoratorFactory","DecoratableErrorBoundary","Component","constructor","props","state","hasError","error","undefined","getDerivedStateFromError","componentDidCatch","errorInfo","console","groupCollapsed","name","groupEnd","render","createElement","style","padding","border","borderRadius","background","color","fontSize","message","children","ComposableContext","displayName","useComposableParents","context","nullRenderer","makeDecoratableComponent","Decoratable","parents","ComposedComponent","Provider","value","staticProps","original","originalName","Object","assign","makeDecoratableHook","hook","decoratableHook","params","composedHook","createVoidComponent","makeDecoratable","hookOrName","component","memo"],"sources":["makeDecoratable.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\";\nimport type { ErrorInfo } from \"react\";\nimport { useComponent } from \"./Context.js\";\nimport type {\n DecoratableComponent,\n DecoratableHook,\n GenericComponent,\n GenericHook\n} from \"~/types.js\";\nimport { withDecoratorFactory, withHookDecoratorFactory } from \"~/decorators.js\";\n\ninterface ErrorBoundaryProps {\n name: string;\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | undefined;\n}\n\nclass DecoratableErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: undefined };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.groupCollapsed(\n `%cCOMPONENT ERROR%c: \"${this.props.name}\" failed to render.`,\n \"color:red\",\n \"color:default\"\n );\n console.error(error, errorInfo);\n console.groupEnd();\n }\n\n override render() {\n if (this.state.hasError) {\n return (\n <div\n style={{\n padding: \"8px 12px\",\n border: \"1px solid #e53e3e\",\n borderRadius: 4,\n background: \"#fff5f5\",\n color: \"#c53030\",\n fontSize: 13\n }}\n >\n <strong>{this.props.name}</strong>: {this.state.error?.message}\n </div>\n );\n }\n return this.props.children;\n }\n}\n\nconst ComposableContext = createContext<string[]>([]);\nComposableContext.displayName = \"ComposableContext\";\n\nfunction useComposableParents() {\n const context = useContext(ComposableContext);\n if (!context) {\n return [];\n }\n\n return context;\n}\n\nconst nullRenderer = () => null;\n\nfunction makeDecoratableComponent<T extends GenericComponent>(\n name: string,\n Component: T = nullRenderer as unknown as T\n) {\n const Decoratable = (props: React.ComponentProps<T>): JSX.Element | null => {\n const parents = useComposableParents();\n const ComposedComponent = useComponent(Component) as GenericComponent<\n React.ComponentProps<T>\n >;\n\n const context = useMemo(() => [...parents, name], [parents, name]);\n\n return (\n <ComposableContext.Provider value={context}>\n <DecoratableErrorBoundary name={name}>\n <ComposedComponent {...props}>{props.children}</ComposedComponent>\n </DecoratableErrorBoundary>\n </ComposableContext.Provider>\n );\n };\n\n const staticProps = {\n original: Component,\n originalName: name,\n displayName: `Decoratable<${name}>`\n };\n\n return withDecoratorFactory()(\n Object.assign(Decoratable, staticProps) as DecoratableComponent<\n typeof Component & typeof staticProps\n >\n );\n}\n\nexport function makeDecoratableHook<T extends GenericHook>(hook: T) {\n const decoratableHook = (params: Parameters<T>) => {\n const composedHook = useComponent(hook);\n\n return composedHook(params) as DecoratableHook<T>;\n };\n\n decoratableHook.original = hook;\n\n return withHookDecoratorFactory()(decoratableHook as DecoratableHook<T>);\n}\n\nexport function createVoidComponent<T>() {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n return (props: T): JSX.Element | null => {\n return null;\n };\n}\n\nexport function makeDecoratable<T extends GenericHook>(\n hook: T\n): ReturnType<typeof makeDecoratableHook<T>>;\nexport function makeDecoratable<T extends GenericComponent>(\n name: string,\n Component: T\n): ReturnType<typeof makeDecoratableComponent<T>>;\nexport function makeDecoratable(hookOrName: any, Component?: any) {\n if (Component) {\n const component = makeDecoratableComponent(hookOrName, React.memo(Component));\n component.original.displayName = hookOrName;\n return component;\n }\n\n return makeDecoratableHook(hookOrName);\n}\n"],"mappings":"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","ignoreList":[]}