react-chain-of-responsibility 0.4.0-main.6548dd9 → 0.4.0-main.a361688
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/dist/{chunk-3IVASMVM.mjs → chunk-U4UF7NZV.mjs} +3 -6
- package/dist/chunk-U4UF7NZV.mjs.map +1 -0
- package/dist/{index-Cx9W9BxD.d.mts → index-Dm_KqEiI.d.mts} +5 -9
- package/dist/{index-Cx9W9BxD.d.ts → index-Dm_KqEiI.d.ts} +5 -9
- package/dist/react-chain-of-responsibility.d.mts +2 -1
- package/dist/react-chain-of-responsibility.d.ts +2 -1
- package/dist/react-chain-of-responsibility.fluentUI.d.mts +2 -1
- package/dist/react-chain-of-responsibility.fluentUI.d.ts +2 -1
- package/dist/react-chain-of-responsibility.fluentUI.js +3 -15
- package/dist/react-chain-of-responsibility.fluentUI.js.map +1 -1
- package/dist/react-chain-of-responsibility.fluentUI.mjs +1 -2
- package/dist/react-chain-of-responsibility.fluentUI.mjs.map +1 -1
- package/dist/react-chain-of-responsibility.js +3 -15
- package/dist/react-chain-of-responsibility.js.map +1 -1
- package/dist/react-chain-of-responsibility.mjs +1 -2
- package/dist/react-chain-of-responsibility.preview.d.mts +15 -8
- package/dist/react-chain-of-responsibility.preview.d.ts +15 -8
- package/dist/react-chain-of-responsibility.preview.js +44 -77
- package/dist/react-chain-of-responsibility.preview.js.map +1 -1
- package/dist/react-chain-of-responsibility.preview.mjs +29 -53
- package/dist/react-chain-of-responsibility.preview.mjs.map +1 -1
- package/package.json +21 -9
- package/dist/chunk-3IVASMVM.mjs.map +0 -1
- package/dist/chunk-TNTIZJJ5.mjs +0 -17
- package/dist/chunk-TNTIZJJ5.mjs.map +0 -1
|
@@ -34,24 +34,12 @@ __export(index_preview_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_preview_exports);
|
|
36
36
|
|
|
37
|
-
// src/createChainOfResponsibilityAsRenderCallback.tsx
|
|
38
|
-
var
|
|
37
|
+
// src/preview/createChainOfResponsibilityAsRenderCallback.tsx
|
|
38
|
+
var import_handler_chain = require("handler-chain");
|
|
39
|
+
var import_react = __toESM(require("react"));
|
|
39
40
|
var import_valibot = require("valibot");
|
|
40
41
|
|
|
41
|
-
// src/private/
|
|
42
|
-
function compose(...fns) {
|
|
43
|
-
return (fn) => fns.reduce((chain, fn2) => fn2(chain), fn);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// src/private/applyMiddleware.ts
|
|
47
|
-
function applyMiddleware(...arrayOfMiddleware) {
|
|
48
|
-
return (...init) => {
|
|
49
|
-
const chain = arrayOfMiddleware.map((middleware) => middleware(...init));
|
|
50
|
-
return compose(...chain);
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// src/private/arePropsEqual.ts
|
|
42
|
+
// src/preview/private/arePropsEqual.ts
|
|
55
43
|
function arePropsEqual(x, y) {
|
|
56
44
|
if (Object.is(x, y)) {
|
|
57
45
|
return true;
|
|
@@ -70,31 +58,21 @@ function arePropsEqual(x, y) {
|
|
|
70
58
|
return true;
|
|
71
59
|
}
|
|
72
60
|
|
|
73
|
-
// src/
|
|
74
|
-
var import_react = require("react");
|
|
75
|
-
var NOT_INITIALIZED = Symbol();
|
|
76
|
-
function useMemoValueWithEquality(factory, equalityFn) {
|
|
77
|
-
const prevRef = (0, import_react.useRef)(NOT_INITIALIZED);
|
|
78
|
-
const next = factory();
|
|
79
|
-
const current = prevRef.current !== NOT_INITIALIZED && equalityFn(prevRef.current, next) ? prevRef.current : next;
|
|
80
|
-
(0, import_react.useEffect)(() => {
|
|
81
|
-
prevRef.current = current;
|
|
82
|
-
});
|
|
83
|
-
return current;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// src/createChainOfResponsibilityAsRenderCallback.tsx
|
|
61
|
+
// src/preview/createChainOfResponsibilityAsRenderCallback.tsx
|
|
87
62
|
var DO_NOT_CREATE_THIS_OBJECT_YOURSELF = Symbol();
|
|
88
|
-
var
|
|
63
|
+
var componentHandlerResultSchema = (0, import_valibot.custom)(
|
|
89
64
|
(value) => (0, import_valibot.safeParse)((0, import_valibot.object)({ render: (0, import_valibot.function_)() }), value).success && !!value && typeof value === "object" && DO_NOT_CREATE_THIS_OBJECT_YOURSELF in value,
|
|
90
65
|
"react-chain-of-responsibility: middleware must return value constructed by reactComponent()"
|
|
91
66
|
);
|
|
67
|
+
function createComponentHandlerResult(render) {
|
|
68
|
+
return Object.freeze({ [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: void 0, render });
|
|
69
|
+
}
|
|
92
70
|
function createChainOfResponsibility(options = {}) {
|
|
93
71
|
options = Object.freeze({ ...options });
|
|
94
|
-
const BuildContext = (0,
|
|
72
|
+
const BuildContext = (0, import_react.createContext)(
|
|
95
73
|
Object.freeze({ enhancer: (next) => (request) => next(request) })
|
|
96
74
|
);
|
|
97
|
-
const RenderContext = (0,
|
|
75
|
+
const RenderContext = (0, import_react.createContext)(
|
|
98
76
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
99
77
|
new Proxy({}, {
|
|
100
78
|
get() {
|
|
@@ -105,36 +83,33 @@ function createChainOfResponsibility(options = {}) {
|
|
|
105
83
|
})
|
|
106
84
|
);
|
|
107
85
|
function reactComponent(component, bindProps) {
|
|
108
|
-
return
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
)
|
|
118
|
-
});
|
|
86
|
+
return createComponentHandlerResult((overridingProps) => /* @__PURE__ */ import_react.default.createElement(
|
|
87
|
+
ComponentWithProps,
|
|
88
|
+
{
|
|
89
|
+
bindProps,
|
|
90
|
+
component,
|
|
91
|
+
overridingProps
|
|
92
|
+
}
|
|
93
|
+
));
|
|
119
94
|
}
|
|
120
|
-
const ComponentWithProps = (0,
|
|
95
|
+
const ComponentWithProps = (0, import_react.memo)(function ComponentWithProps2({
|
|
121
96
|
bindProps,
|
|
122
97
|
component: Component,
|
|
123
98
|
overridingProps
|
|
124
99
|
}) {
|
|
125
100
|
const { allowOverrideProps } = options;
|
|
126
|
-
const { renderCallbackProps } = (0,
|
|
101
|
+
const { originalProps: renderCallbackProps } = (0, import_react.useContext)(RenderContext);
|
|
127
102
|
if (overridingProps && !arePropsEqual(overridingProps, renderCallbackProps) && !allowOverrideProps) {
|
|
128
103
|
console.warn('react-chain-of-responsibility: "allowOverrideProps" must be set to true to override props');
|
|
129
104
|
}
|
|
130
105
|
const props = Object.freeze(
|
|
131
106
|
allowOverrideProps ? { ...renderCallbackProps, ...overridingProps } : { ...renderCallbackProps }
|
|
132
107
|
);
|
|
133
|
-
return /* @__PURE__ */
|
|
108
|
+
return /* @__PURE__ */ import_react.default.createElement(Component, { ...props, ...typeof bindProps === "function" ? bindProps(props) : bindProps });
|
|
134
109
|
});
|
|
135
110
|
const useBuildRenderCallback = () => {
|
|
136
|
-
const { enhancer } = (0,
|
|
137
|
-
return (0,
|
|
111
|
+
const { enhancer } = (0, import_react.useContext)(BuildContext);
|
|
112
|
+
return (0, import_react.useCallback)(
|
|
138
113
|
(request, buildOptions = {}) => {
|
|
139
114
|
const result = (
|
|
140
115
|
// Put the "fallbackComponent" as the last one in the chain.
|
|
@@ -147,34 +122,26 @@ function createChainOfResponsibility(options = {}) {
|
|
|
147
122
|
);
|
|
148
123
|
return;
|
|
149
124
|
}
|
|
150
|
-
return
|
|
151
|
-
// Mark fallback render callback as functor return value.
|
|
152
|
-
[DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: void 0,
|
|
153
|
-
render: () => (
|
|
154
|
-
// Currently, there are no ways to set `bindProps` to `fallbackComponent`.
|
|
155
|
-
// `fallbackComponent` do not need `overridingProps` because it is the last one in the chain, it would not have the next() function.
|
|
156
|
-
/* @__PURE__ */ import_react2.default.createElement(ComponentWithProps, { component: fallbackComponent })
|
|
157
|
-
)
|
|
158
|
-
});
|
|
125
|
+
return reactComponent(fallbackComponent);
|
|
159
126
|
})(request)
|
|
160
127
|
);
|
|
161
|
-
return result && ((
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
[renderCallbackProps]
|
|
166
|
-
);
|
|
167
|
-
return /* @__PURE__ */ import_react2.default.createElement(RenderContext.Provider, { value: context }, result.render());
|
|
168
|
-
});
|
|
128
|
+
return result && ((originalProps) => (
|
|
129
|
+
// This is render function, we cannot call any hooks here.
|
|
130
|
+
/* @__PURE__ */ import_react.default.createElement(BuildRenderCallback, { originalProps, render: result.render })
|
|
131
|
+
));
|
|
169
132
|
},
|
|
170
133
|
[enhancer]
|
|
171
134
|
);
|
|
172
135
|
};
|
|
136
|
+
function BuildRenderCallback({ originalProps, render }) {
|
|
137
|
+
const context = (0, import_react.useMemo)(() => Object.freeze({ originalProps }), [originalProps]);
|
|
138
|
+
return /* @__PURE__ */ import_react.default.createElement(RenderContext.Provider, { value: context }, render());
|
|
139
|
+
}
|
|
173
140
|
function ChainOfResponsibilityProvider({ children, init, middleware }) {
|
|
174
141
|
if (!Array.isArray(middleware) || middleware.some((middleware2) => typeof middleware2 !== "function")) {
|
|
175
142
|
throw new Error('react-chain-of-responsibility: "middleware" prop must be an array of functions');
|
|
176
143
|
}
|
|
177
|
-
const fortifiedMiddleware = (0,
|
|
144
|
+
const fortifiedMiddleware = (0, import_react.useMemo)(
|
|
178
145
|
() => Object.freeze(
|
|
179
146
|
middleware.map((fn) => (init2) => {
|
|
180
147
|
const enhancer2 = fn(init2);
|
|
@@ -192,35 +159,35 @@ function createChainOfResponsibility(options = {}) {
|
|
|
192
159
|
return next(options.passModifiedRequest ? nextRequest : originalRequest);
|
|
193
160
|
})(originalRequest);
|
|
194
161
|
hasReturned = true;
|
|
195
|
-
return returnValue && (0, import_valibot.parse)(
|
|
162
|
+
return returnValue && (0, import_valibot.parse)(componentHandlerResultSchema, returnValue);
|
|
196
163
|
};
|
|
197
164
|
})
|
|
198
165
|
),
|
|
199
166
|
[middleware]
|
|
200
167
|
);
|
|
201
|
-
const { enhancer: parentEnhancer } = (0,
|
|
202
|
-
const enhancer = (0,
|
|
168
|
+
const { enhancer: parentEnhancer } = (0, import_react.useContext)(BuildContext);
|
|
169
|
+
const enhancer = (0, import_react.useMemo)(
|
|
203
170
|
() => (
|
|
204
171
|
// We are reversing because it is easier to read:
|
|
205
172
|
// - With reverse, [a, b, c] will become a(b(c(fn)))
|
|
206
173
|
// - Without reverse, [a, b, c] will become c(b(a(fn)))
|
|
207
|
-
applyMiddleware(
|
|
208
|
-
...[...fortifiedMiddleware, ...[() => parentEnhancer]]
|
|
174
|
+
(0, import_handler_chain.applyMiddleware)(
|
|
175
|
+
...[...fortifiedMiddleware, ...[() => parentEnhancer]]
|
|
209
176
|
)(init)
|
|
210
177
|
),
|
|
211
178
|
[init, fortifiedMiddleware, parentEnhancer]
|
|
212
179
|
);
|
|
213
|
-
const contextValue = (0,
|
|
214
|
-
return /* @__PURE__ */
|
|
180
|
+
const contextValue = (0, import_react.useMemo)(() => Object.freeze({ enhancer }), [enhancer]);
|
|
181
|
+
return /* @__PURE__ */ import_react.default.createElement(BuildContext.Provider, { value: contextValue }, children);
|
|
215
182
|
}
|
|
216
183
|
function ChainOfResponsibilityProxy({ fallbackComponent, request, ...props }) {
|
|
217
184
|
const result = useBuildRenderCallback()(request, { fallbackComponent })?.(props);
|
|
218
|
-
return result ? /* @__PURE__ */
|
|
185
|
+
return result ? /* @__PURE__ */ import_react.default.createElement(import_react.Fragment, null, result) : null;
|
|
219
186
|
}
|
|
220
|
-
const MemoizedChainOfResponsibilityProvider = (0,
|
|
187
|
+
const MemoizedChainOfResponsibilityProvider = (0, import_react.memo)(ChainOfResponsibilityProvider);
|
|
221
188
|
return Object.freeze({
|
|
222
189
|
Provider: MemoizedChainOfResponsibilityProvider,
|
|
223
|
-
Proxy:
|
|
190
|
+
Proxy: ChainOfResponsibilityProxy,
|
|
224
191
|
reactComponent,
|
|
225
192
|
useBuildRenderCallback
|
|
226
193
|
// TODO: Consider adding back `asMiddleware`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.preview.ts","../src/createChainOfResponsibilityAsRenderCallback.tsx","../src/private/compose.ts","../src/private/applyMiddleware.ts","../src/private/arePropsEqual.ts","../src/private/useMemoValueWithEquality.ts"],"sourcesContent":["export { default as createChainOfResponsibility } from './createChainOfResponsibilityAsRenderCallback.tsx';\n","import React, {\n createContext,\n Fragment,\n memo,\n useCallback,\n useContext,\n useMemo,\n type ComponentType,\n type PropsWithChildren,\n type ReactNode\n} from 'react';\nimport { custom, function_, object, parse, safeParse } from 'valibot';\n\nimport applyMiddleware from './private/applyMiddleware.ts';\nimport arePropsEqual from './private/arePropsEqual.ts';\nimport useMemoValueWithEquality from './private/useMemoValueWithEquality.ts';\n\n// TODO: Related to https://github.com/microsoft/TypeScript/issues/17002.\n// typescript@5.2.2 has a bug, Array.isArray() is a type predicate but only works with mutable array, not readonly array.\ndeclare global {\n interface ArrayConstructor {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n isArray(arg: any): arg is readonly any[];\n }\n}\n\ntype BaseProps = object;\n\ntype RenderCallback<Props extends BaseProps> = (props: Props) => ReactNode;\n\ntype CreateChainOfResponsibilityOptions = {\n /**\n * Allows one component to pass different set of props to its downstream component. Default is false.\n *\n * It is recommended to keep this settings as default to prevent newly added component from unexpectedly changing behavior of downstream components.\n */\n readonly allowOverrideProps?: boolean | undefined;\n\n /**\n * Allows a middleware to pass another request object when calling its next middleware. Default is false.\n *\n * It is recommended to keep this settings as default ot prevent newly added middleware from unexpectedly changing behavior of downstream middleware.\n *\n * To prevent upstream middleware from modifying the request, the request object should be set to be immutable through `Object.freeze`.\n */\n readonly passModifiedRequest?: boolean | undefined;\n};\n\ntype ChainOfResponsibility<Request, Props extends BaseProps, Init> = {\n readonly Provider: ComponentType<ProviderProps<Request, Props, Init>> & InferenceHelper<Request, Props, Init>;\n readonly Proxy: ComponentType<ProxyProps<Request, Props>>;\n readonly reactComponent: <P extends Props>(\n component: ComponentType<P>,\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n ) => ComponentFunctorReturnValue<Props>;\n readonly useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props>;\n};\n\nconst DO_NOT_CREATE_THIS_OBJECT_YOURSELF = Symbol();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst componentFunctorReturnValueSchema = custom<ComponentFunctorReturnValue<any>>(\n value =>\n safeParse(object({ render: function_() }), value).success &&\n !!value &&\n typeof value === 'object' &&\n DO_NOT_CREATE_THIS_OBJECT_YOURSELF in value,\n 'react-chain-of-responsibility: middleware must return value constructed by reactComponent()'\n);\n\ninterface ComponentFunctorReturnValue<Props extends BaseProps> {\n readonly [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined;\n readonly render: (overridingProps?: Partial<Props> | undefined) => ReactNode;\n}\n\ntype ComponentFunctor<Request, Props extends BaseProps> = (\n request: Request\n) => ComponentFunctorReturnValue<Props> | undefined;\n\ntype ComponentEnhancer<Request, Props extends BaseProps> = (\n next: ComponentFunctor<Request, Props>\n) => ComponentFunctor<Request, Props>;\n\ntype ComponentMiddleware<Request, Props extends BaseProps, Init = undefined> = (\n init: Init\n) => ComponentEnhancer<Request, Props>;\n\ntype UseBuildRenderCallbackOptions<Props> = {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n};\n\ninterface UseBuildRenderCallback<Request, Props extends BaseProps> {\n (request: Request, options?: undefined | UseBuildRenderCallbackOptions<Props>): RenderCallback<Props> | undefined;\n}\n\ntype BuildContextType<Request, Props extends BaseProps> = {\n readonly enhancer: ComponentEnhancer<Request, Props>;\n};\n\ntype RenderContextType<Props> = {\n readonly renderCallbackProps: Props;\n};\n\ntype ProviderProps<Request, Props extends BaseProps, Init> = PropsWithChildren<{\n readonly middleware: readonly ComponentMiddleware<Request, Props, Init>[];\n}> &\n (Init extends never | void\n ? { readonly init?: undefined }\n : Init extends undefined | void\n ? { readonly init?: Init }\n : { readonly init: Init });\n\ntype ProxyProps<Request, Props extends BaseProps> = Props & {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n readonly request: Request;\n};\n\ntype InferenceHelper<Request, Props extends BaseProps, Init> = {\n readonly '~types': {\n readonly component: ComponentType<Props>;\n readonly init: Init;\n readonly middleware: ComponentMiddleware<Request, Props, Init>;\n readonly props: Props;\n readonly proxyProps: ProxyProps<Request, Props>;\n readonly request: Request;\n };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferComponent<T extends InferenceHelper<any, any, any>> = T['~types']['component'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferInit<T extends InferenceHelper<any, any, any>> = T['~types']['init'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferMiddleware<T extends InferenceHelper<any, any, any>> = T['~types']['middleware'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProps<T extends InferenceHelper<any, any, any>> = T['~types']['props'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProxyProps<T extends InferenceHelper<any, any, any>> = T['~types']['proxyProps'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferRequest<T extends InferenceHelper<any, any, any>> = T['~types']['request'];\n\nfunction createChainOfResponsibility<\n Request = void,\n Props extends BaseProps = { readonly children?: never },\n Init = void\n>(options: CreateChainOfResponsibilityOptions = {}): ChainOfResponsibility<Request, Props, Init> {\n // Freeze options to prevent accidental change.\n options = Object.freeze({ ...options });\n\n const BuildContext = createContext<BuildContextType<Request, Props>>(\n Object.freeze({ enhancer: next => request => next(request) })\n );\n\n const RenderContext = createContext<RenderContextType<Props>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new Proxy({} as any, {\n get() {\n // The following is assertion, there is no way to hit this line.\n /* istanbul ignore next */\n throw new Error(\n 'react-chain-of-responsibility: this hook cannot be used outside of <Proxy> and useBuildRenderCallback()'\n );\n }\n })\n );\n\n function reactComponent<P extends Props>(\n component: ComponentType<P>,\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n ): ComponentFunctorReturnValue<Props> {\n return Object.freeze({\n [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined,\n render: (overridingProps?: Partial<Props> | undefined) => (\n <ComponentWithProps\n bindProps={bindProps}\n component={component as ComponentType<Props>}\n overridingProps={overridingProps}\n />\n )\n });\n }\n\n const ComponentWithProps = memo(function ComponentWithProps({\n bindProps,\n component: Component,\n overridingProps\n }: {\n readonly bindProps?: Partial<Props> | ((props: Props) => Partial<Props>) | undefined;\n readonly component: ComponentType<Props>;\n readonly overridingProps?: Partial<Props> | undefined;\n }) {\n const { allowOverrideProps } = options;\n const { renderCallbackProps } = useContext(RenderContext);\n\n if (overridingProps && !arePropsEqual(overridingProps, renderCallbackProps) && !allowOverrideProps) {\n console.warn('react-chain-of-responsibility: \"allowOverrideProps\" must be set to true to override props');\n }\n\n const props = Object.freeze(\n allowOverrideProps ? { ...renderCallbackProps, ...overridingProps } : { ...renderCallbackProps }\n );\n\n return <Component {...props} {...(typeof bindProps === 'function' ? bindProps(props) : bindProps)} />;\n });\n\n const useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props> = () => {\n const { enhancer } = useContext(BuildContext);\n\n return useCallback(\n (request, buildOptions = {}) => {\n const result =\n // Put the \"fallbackComponent\" as the last one in the chain.\n enhancer(() => {\n const { fallbackComponent } = buildOptions;\n\n if (!fallbackComponent) {\n console.warn(\n 'react-chain-of-responsibility: the request has fall through all middleware, set \"fallbackComponent\" as a catchall',\n request\n );\n\n // For clarity, we are returning `undefined` instead of `() => undefined`.\n return;\n }\n\n return Object.freeze({\n // Mark fallback render callback as functor return value.\n [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined,\n render: () => (\n // Currently, there are no ways to set `bindProps` to `fallbackComponent`.\n // `fallbackComponent` do not need `overridingProps` because it is the last one in the chain, it would not have the next() function.\n <ComponentWithProps component={fallbackComponent} />\n )\n });\n })(request);\n\n return (\n result &&\n ((props: Props) => {\n const renderCallbackProps = useMemoValueWithEquality<Props>(() => props, arePropsEqual);\n\n const context = useMemo<RenderContextType<Props>>(\n () => Object.freeze({ renderCallbackProps }),\n [renderCallbackProps]\n );\n\n return <RenderContext.Provider value={context}>{result.render()}</RenderContext.Provider>;\n })\n );\n },\n [enhancer]\n );\n };\n\n function ChainOfResponsibilityProvider({ children, init, middleware }: ProviderProps<Request, Props, Init>) {\n if (!Array.isArray(middleware) || middleware.some(middleware => typeof middleware !== 'function')) {\n throw new Error('react-chain-of-responsibility: \"middleware\" prop must be an array of functions');\n }\n\n // Remap the middleware, so all inputs/outputs are validated.\n const fortifiedMiddleware = useMemo(\n () =>\n Object.freeze(\n middleware.map<ComponentMiddleware<Request, Props, Init>>(fn => (init: Init) => {\n const enhancer = fn(init);\n\n return next => originalRequest => {\n // False positive: although we did not re-assign the variable from true, it was initialized as undefined.\n // eslint-disable-next-line prefer-const\n let hasReturned: boolean;\n\n const returnValue = enhancer(nextRequest => {\n if (hasReturned) {\n throw new Error(\n 'react-chain-of-responsibility: next() cannot be called after the function had returned synchronously'\n );\n }\n\n // We do not allow passing void/undefined to next() because it would be confusing whether to keep the original request or pass an undefined.\n !options.passModifiedRequest &&\n !Object.is(nextRequest, originalRequest) &&\n console.warn(\n 'react-chain-of-responsibility: next() must be called with the original request, otherwise, set \"options.passModifiedRequest\" to true to pass a different request object downstream'\n );\n\n return next(options.passModifiedRequest ? nextRequest : originalRequest);\n })(originalRequest);\n\n hasReturned = true;\n\n // Make sure the return value is built using our helper function for forward-compatibility reason.\n return returnValue && parse(componentFunctorReturnValueSchema, returnValue);\n };\n })\n ),\n [middleware]\n );\n\n const { enhancer: parentEnhancer } = useContext(BuildContext);\n\n const enhancer = useMemo<ComponentEnhancer<Request, Props>>(\n () =>\n // We are reversing because it is easier to read:\n // - With reverse, [a, b, c] will become a(b(c(fn)))\n // - Without reverse, [a, b, c] will become c(b(a(fn)))\n applyMiddleware<[Request], ComponentFunctorReturnValue<Props> | undefined, [Init]>(\n ...[...fortifiedMiddleware, ...[() => parentEnhancer]].reverse()\n )(init as Init),\n [init, fortifiedMiddleware, parentEnhancer]\n );\n\n const contextValue = useMemo<BuildContextType<Request, Props>>(() => Object.freeze({ enhancer }), [enhancer]);\n\n return <BuildContext.Provider value={contextValue}>{children}</BuildContext.Provider>;\n }\n\n function ChainOfResponsibilityProxy({ fallbackComponent, request, ...props }: ProxyProps<Request, Props>) {\n const result = useBuildRenderCallback()(request, { fallbackComponent })?.(props as Props);\n\n return result ? <Fragment>{result}</Fragment> : null;\n }\n\n const MemoizedChainOfResponsibilityProvider =\n memo<ProviderProps<Request, Props, Init>>(ChainOfResponsibilityProvider);\n\n return Object.freeze({\n Provider: MemoizedChainOfResponsibilityProvider as typeof MemoizedChainOfResponsibilityProvider &\n InferenceHelper<Request, Props, Init>,\n Proxy: memo<ProxyProps<Request, Props>>(ChainOfResponsibilityProxy),\n reactComponent,\n useBuildRenderCallback\n\n // TODO: Consider adding back `asMiddleware`.\n });\n}\n\nexport default createChainOfResponsibility;\nexport {\n type ChainOfResponsibility,\n type CreateChainOfResponsibilityOptions,\n type InferComponent,\n type InferInit,\n type InferMiddleware,\n type InferProps,\n type InferProxyProps,\n type InferRequest,\n type UseBuildRenderCallback\n};\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Fn<P extends any[], R> = (...args: P) => R;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Enhancer<P extends any[], R> = (next: Fn<P, R>) => Fn<P, R>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function compose<P extends any[], R>(...fns: Enhancer<P, R>[]): Enhancer<P, R> {\n return (fn: Fn<P, R>): Fn<P, R> => fns.reduce((chain, fn) => fn(chain), fn);\n}\n","import compose from './compose.ts';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Fn<P extends any[], R> = (...args: P) => R;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Enhancer<P extends any[], R> = (next: Fn<P, R>) => Fn<P, R>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Middleware<P extends any[], R, S extends any[]> = (...init: S) => Enhancer<P, R>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function applyMiddleware<P extends any[], R, S extends any[]>(\n ...arrayOfMiddleware: Middleware<P, R, S>[]\n) {\n return (...init: S) => {\n const chain = arrayOfMiddleware.map(middleware => middleware(...init));\n\n return compose(...chain);\n };\n}\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function arePropsEqual<T extends Record<string, any>>(x: T, y: T): boolean {\n if (Object.is(x, y)) {\n return true;\n }\n\n const mapOfX = new Map(Object.entries(x));\n const mapOfY = new Map(Object.entries(y));\n\n if (mapOfX.size !== mapOfY.size) {\n return false;\n }\n\n const keys = new Set([...mapOfX.keys(), ...mapOfY.keys()]);\n\n for (const key of keys) {\n if (!Object.is(mapOfX.get(key), mapOfY.get(key))) {\n return false;\n }\n }\n\n return true;\n}\n","import { useEffect, useRef } from 'react';\n\nconst NOT_INITIALIZED = Symbol();\n\nexport default function useMemoValueWithEquality<T>(factory: () => T, equalityFn: (x: T, y: T) => boolean): T {\n const prevRef = useRef<T | typeof NOT_INITIALIZED>(NOT_INITIALIZED);\n const next: T = factory();\n const current: T = prevRef.current !== NOT_INITIALIZED && equalityFn(prevRef.current, next) ? prevRef.current : next;\n\n useEffect(() => {\n prevRef.current = current;\n });\n\n return current;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAUO;AACP,qBAA4D;;;ACJ7C,SAAR,WAAgD,KAAuC;AAC5F,SAAO,CAAC,OAA2B,IAAI,OAAO,CAAC,OAAOC,QAAOA,IAAG,KAAK,GAAG,EAAE;AAC5E;;;ACGe,SAAR,mBACF,mBACH;AACA,SAAO,IAAI,SAAY;AACrB,UAAM,QAAQ,kBAAkB,IAAI,gBAAc,WAAW,GAAG,IAAI,CAAC;AAErE,WAAO,QAAQ,GAAG,KAAK;AAAA,EACzB;AACF;;;ACnBe,SAAR,cAA8D,GAAM,GAAe;AACxF,MAAI,OAAO,GAAG,GAAG,CAAC,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,IAAI,IAAI,OAAO,QAAQ,CAAC,CAAC;AACxC,QAAM,SAAS,IAAI,IAAI,OAAO,QAAQ,CAAC,CAAC;AAExC,MAAI,OAAO,SAAS,OAAO,MAAM;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC;AAEzD,aAAW,OAAO,MAAM;AACtB,QAAI,CAAC,OAAO,GAAG,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,GAAG,CAAC,GAAG;AAChD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;ACtBA,mBAAkC;AAElC,IAAM,kBAAkB,OAAO;AAEhB,SAAR,yBAA6C,SAAkB,YAAwC;AAC5G,QAAM,cAAU,qBAAmC,eAAe;AAClE,QAAM,OAAU,QAAQ;AACxB,QAAM,UAAa,QAAQ,YAAY,mBAAmB,WAAW,QAAQ,SAAS,IAAI,IAAI,QAAQ,UAAU;AAEhH,8BAAU,MAAM;AACd,YAAQ,UAAU;AAAA,EACpB,CAAC;AAED,SAAO;AACT;;;AJ+CA,IAAM,qCAAqC,OAAO;AAGlD,IAAM,wCAAoC;AAAA,EACxC,eACE,8BAAU,uBAAO,EAAE,YAAQ,0BAAU,EAAE,CAAC,GAAG,KAAK,EAAE,WAClD,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,sCAAsC;AAAA,EACxC;AACF;AAyEA,SAAS,4BAIP,UAA8C,CAAC,GAAgD;AAE/F,YAAU,OAAO,OAAO,EAAE,GAAG,QAAQ,CAAC;AAEtC,QAAM,mBAAe;AAAA,IACnB,OAAO,OAAO,EAAE,UAAU,UAAQ,aAAW,KAAK,OAAO,EAAE,CAAC;AAAA,EAC9D;AAEA,QAAM,oBAAgB;AAAA;AAAA,IAEpB,IAAI,MAAM,CAAC,GAAU;AAAA,MACnB,MAAM;AAGJ,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,eACP,WACA,WAIoC;AACpC,WAAO,OAAO,OAAO;AAAA,MACnB,CAAC,kCAAkC,GAAG;AAAA,MACtC,QAAQ,CAAC,oBACP,8BAAAC,QAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,IAEJ,CAAC;AAAA,EACH;AAEA,QAAM,yBAAqB,oBAAK,SAASC,oBAAmB;AAAA,IAC1D;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF,GAIG;AACD,UAAM,EAAE,mBAAmB,IAAI;AAC/B,UAAM,EAAE,oBAAoB,QAAI,0BAAW,aAAa;AAExD,QAAI,mBAAmB,CAAC,cAAc,iBAAiB,mBAAmB,KAAK,CAAC,oBAAoB;AAClG,cAAQ,KAAK,2FAA2F;AAAA,IAC1G;AAEA,UAAM,QAAQ,OAAO;AAAA,MACnB,qBAAqB,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,IAAI,EAAE,GAAG,oBAAoB;AAAA,IACjG;AAEA,WAAO,8BAAAD,QAAA,cAAC,aAAW,GAAG,OAAQ,GAAI,OAAO,cAAc,aAAa,UAAU,KAAK,IAAI,WAAY;AAAA,EACrG,CAAC;AAED,QAAM,yBAAuE,MAAM;AACjF,UAAM,EAAE,SAAS,QAAI,0BAAW,YAAY;AAE5C,eAAO;AAAA,MACL,CAAC,SAAS,eAAe,CAAC,MAAM;AAC9B,cAAM;AAAA;AAAA,UAEJ,SAAS,MAAM;AACb,kBAAM,EAAE,kBAAkB,IAAI;AAE9B,gBAAI,CAAC,mBAAmB;AACtB,sBAAQ;AAAA,gBACN;AAAA,gBACA;AAAA,cACF;AAGA;AAAA,YACF;AAEA,mBAAO,OAAO,OAAO;AAAA;AAAA,cAEnB,CAAC,kCAAkC,GAAG;AAAA,cACtC,QAAQ;AAAA;AAAA;AAAA,gBAGN,8BAAAA,QAAA,cAAC,sBAAmB,WAAW,mBAAmB;AAAA;AAAA,YAEtD,CAAC;AAAA,UACH,CAAC,EAAE,OAAO;AAAA;AAEZ,eACE,WACC,CAAC,UAAiB;AACjB,gBAAM,sBAAsB,yBAAgC,MAAM,OAAO,aAAa;AAEtF,gBAAM,cAAU;AAAA,YACd,MAAM,OAAO,OAAO,EAAE,oBAAoB,CAAC;AAAA,YAC3C,CAAC,mBAAmB;AAAA,UACtB;AAEA,iBAAO,8BAAAA,QAAA,cAAC,cAAc,UAAd,EAAuB,OAAO,WAAU,OAAO,OAAO,CAAE;AAAA,QAClE;AAAA,MAEJ;AAAA,MACA,CAAC,QAAQ;AAAA,IACX;AAAA,EACF;AAEA,WAAS,8BAA8B,EAAE,UAAU,MAAM,WAAW,GAAwC;AAC1G,QAAI,CAAC,MAAM,QAAQ,UAAU,KAAK,WAAW,KAAK,CAAAE,gBAAc,OAAOA,gBAAe,UAAU,GAAG;AACjG,YAAM,IAAI,MAAM,gFAAgF;AAAA,IAClG;AAGA,UAAM,0BAAsB;AAAA,MAC1B,MACE,OAAO;AAAA,QACL,WAAW,IAA+C,QAAM,CAACC,UAAe;AAC9E,gBAAMC,YAAW,GAAGD,KAAI;AAExB,iBAAO,UAAQ,qBAAmB;AAGhC,gBAAI;AAEJ,kBAAM,cAAcC,UAAS,iBAAe;AAC1C,kBAAI,aAAa;AACf,sBAAM,IAAI;AAAA,kBACR;AAAA,gBACF;AAAA,cACF;AAGA,eAAC,QAAQ,uBACP,CAAC,OAAO,GAAG,aAAa,eAAe,KACvC,QAAQ;AAAA,gBACN;AAAA,cACF;AAEF,qBAAO,KAAK,QAAQ,sBAAsB,cAAc,eAAe;AAAA,YACzE,CAAC,EAAE,eAAe;AAElB,0BAAc;AAGd,mBAAO,mBAAe,sBAAM,mCAAmC,WAAW;AAAA,UAC5E;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACF,CAAC,UAAU;AAAA,IACb;AAEA,UAAM,EAAE,UAAU,eAAe,QAAI,0BAAW,YAAY;AAE5D,UAAM,eAAW;AAAA,MACf;AAAA;AAAA;AAAA;AAAA,QAIE;AAAA,UACE,GAAG,CAAC,GAAG,qBAAqB,GAAG,CAAC,MAAM,cAAc,CAAC,EAAE,QAAQ;AAAA,QACjE,EAAE,IAAY;AAAA;AAAA,MAChB,CAAC,MAAM,qBAAqB,cAAc;AAAA,IAC5C;AAEA,UAAM,mBAAe,uBAA0C,MAAM,OAAO,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;AAE5G,WAAO,8BAAAJ,QAAA,cAAC,aAAa,UAAb,EAAsB,OAAO,gBAAe,QAAS;AAAA,EAC/D;AAEA,WAAS,2BAA2B,EAAE,mBAAmB,SAAS,GAAG,MAAM,GAA+B;AACxG,UAAM,SAAS,uBAAuB,EAAE,SAAS,EAAE,kBAAkB,CAAC,IAAI,KAAc;AAExF,WAAO,SAAS,8BAAAA,QAAA,cAAC,8BAAU,MAAO,IAAc;AAAA,EAClD;AAEA,QAAM,4CACJ,oBAA0C,6BAA6B;AAEzE,SAAO,OAAO,OAAO;AAAA,IACnB,UAAU;AAAA,IAEV,WAAO,oBAAiC,0BAA0B;AAAA,IAClE;AAAA,IACA;AAAA;AAAA,EAGF,CAAC;AACH;AAEA,IAAO,sDAAQ;","names":["import_react","fn","React","ComponentWithProps","middleware","init","enhancer"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.preview.ts","../src/preview/createChainOfResponsibilityAsRenderCallback.tsx","../src/preview/private/arePropsEqual.ts"],"sourcesContent":["export {\n default as createChainOfResponsibility,\n type ChainOfResponsibility,\n type ComponentEnhancer,\n type ComponentHandler,\n type ComponentHandlerResult,\n type ComponentMiddleware,\n type ComponentRenderer,\n type CreateChainOfResponsibilityOptions,\n type InferenceHelper,\n type InferInit,\n type InferMiddleware,\n type InferProps,\n type InferProviderProps,\n type InferProxyProps,\n type InferRequest,\n type ProviderProps,\n type ProxyProps,\n type ReactComponentHandlerResult,\n type UseBuildRenderCallback,\n type UseBuildRenderCallbackOptions\n} from './preview/createChainOfResponsibilityAsRenderCallback.tsx';\n","import { applyMiddleware } from 'handler-chain';\nimport React, {\n createContext,\n Fragment,\n memo,\n useCallback,\n useContext,\n useMemo,\n type ComponentType,\n type PropsWithChildren,\n type ReactNode\n} from 'react';\nimport { custom, function_, object, parse, safeParse } from 'valibot';\n\nimport arePropsEqual from './private/arePropsEqual.ts';\n\n// TODO: Related to https://github.com/microsoft/TypeScript/issues/17002.\n// typescript@5.2.2 has a bug, Array.isArray() is a type predicate but only works with mutable array, not readonly array.\ndeclare global {\n interface ArrayConstructor {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n isArray(arg: any): arg is readonly any[];\n }\n}\n\ntype BaseProps = object;\n\ntype CreateChainOfResponsibilityOptions = {\n /**\n * Allows one component to pass different set of props to its downstream component. Default is false.\n *\n * It is recommended to keep this settings as default to prevent newly added component from unexpectedly changing behavior of downstream components.\n */\n readonly allowOverrideProps?: boolean | undefined;\n\n /**\n * Allows a middleware to pass another request object when calling its next middleware. Default is false.\n *\n * It is recommended to keep this settings as default ot prevent newly added middleware from unexpectedly changing behavior of downstream middleware.\n *\n * To prevent upstream middleware from modifying the request, the request object should be set to be immutable through `Object.freeze`.\n */\n readonly passModifiedRequest?: boolean | undefined;\n};\n\ntype ChainOfResponsibility<Request, Props extends BaseProps, Init> = {\n readonly Provider: ComponentType<ProviderProps<Request, Props, Init>> & InferenceHelper<Request, Props, Init>;\n readonly Proxy: ComponentType<ProxyProps<Request, Props>>;\n readonly reactComponent: ReactComponentHandlerResult<Props>;\n readonly useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props>;\n};\n\n// TODO: Maybe this one should be local.\n// Verify that reactComponent() from an instance of CoR should throw error when used in another instance of CoR.\nconst DO_NOT_CREATE_THIS_OBJECT_YOURSELF = Symbol();\n\ntype ComponentRenderer<Props> = (props: Props) => ReactNode;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst componentHandlerResultSchema = custom<ComponentHandlerResult<any>>(\n value =>\n safeParse(object({ render: function_() }), value).success &&\n !!value &&\n typeof value === 'object' &&\n DO_NOT_CREATE_THIS_OBJECT_YOURSELF in value,\n 'react-chain-of-responsibility: middleware must return value constructed by reactComponent()'\n);\n\ninterface ComponentHandlerResult<Props extends BaseProps> {\n readonly [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined;\n readonly render: (overridingProps?: Partial<Props> | undefined) => ReactNode;\n}\n\ntype ComponentHandler<Request, Props extends BaseProps> = (\n request: Request\n) => ComponentHandlerResult<Props> | undefined;\n\ntype ComponentEnhancer<Request, Props extends BaseProps> = (\n next: ComponentHandler<Request, Props>\n) => ComponentHandler<Request, Props>;\n\ntype ComponentMiddleware<Request, Props extends BaseProps, Init = undefined> = (\n init: Init\n) => ComponentEnhancer<Request, Props>;\n\ntype ReactComponentHandlerResult<Props extends object> = <P extends Props>(\n component: ComponentType<P>,\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n) => ComponentHandlerResult<Props>;\n\ntype UseBuildRenderCallbackOptions<Props> = {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n};\n\ninterface UseBuildRenderCallback<Request, Props extends BaseProps> {\n (request: Request, options?: undefined | UseBuildRenderCallbackOptions<Props>): ComponentRenderer<Props> | undefined;\n}\n\ntype BuildContextType<Request, Props extends BaseProps> = {\n readonly enhancer: ComponentEnhancer<Request, Props>;\n};\n\ntype RenderContextType<Props> = {\n readonly originalProps: Props;\n};\n\ntype ProviderProps<Request, Props extends BaseProps, Init> = PropsWithChildren<{\n readonly middleware: readonly ComponentMiddleware<Request, Props, Init>[];\n}> &\n (Init extends never | void\n ? { readonly init?: undefined }\n : Init extends undefined | void\n ? { readonly init?: Init }\n : { readonly init: Init });\n\ntype ProxyProps<Request, Props extends BaseProps> = Props & {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n readonly request: Request;\n};\n\ntype InferenceHelper<Request, Props extends BaseProps, Init> = {\n readonly '~types': {\n readonly init: Init;\n readonly middleware: ComponentMiddleware<Request, Props, Init>;\n readonly props: Props;\n readonly proxyProps: ProxyProps<Request, Props>;\n readonly providerProps: ProviderProps<Request, Props, Init>;\n readonly request: Request;\n };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferInit<T extends InferenceHelper<any, any, any>> = T['~types']['init'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferMiddleware<T extends InferenceHelper<any, any, any>> = T['~types']['middleware'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProps<T extends InferenceHelper<any, any, any>> = T['~types']['props'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProxyProps<T extends InferenceHelper<any, any, any>> = T['~types']['proxyProps'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProviderProps<T extends InferenceHelper<any, any, any>> = T['~types']['providerProps'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferRequest<T extends InferenceHelper<any, any, any>> = T['~types']['request'];\n\nfunction createComponentHandlerResult<Props extends BaseProps>(\n render: (overridingProps?: Partial<Props> | undefined) => ReactNode\n): ComponentHandlerResult<Props> {\n return Object.freeze({ [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined, render });\n}\n\nfunction createChainOfResponsibility<\n Request = void,\n Props extends BaseProps = { readonly children?: never },\n Init = void\n>(options: CreateChainOfResponsibilityOptions = {}): ChainOfResponsibility<Request, Props, Init> {\n // Freeze options to prevent accidental change.\n options = Object.freeze({ ...options });\n\n const BuildContext = createContext<BuildContextType<Request, Props>>(\n Object.freeze({ enhancer: next => request => next(request) })\n );\n\n const RenderContext = createContext<RenderContextType<Props>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new Proxy({} as any, {\n get() {\n // The following is assertion, there is no way to hit this line.\n /* istanbul ignore next */\n throw new Error(\n 'react-chain-of-responsibility: this hook cannot be used outside of <Proxy> and useBuildRenderCallback()'\n );\n }\n })\n );\n\n function reactComponent<P extends Props>(\n component: ComponentType<P>,\n // For `bindProps` of type function, do not do side-effect in it, it may not be always called in all scenarios.\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n ): ComponentHandlerResult<Props> {\n return createComponentHandlerResult((overridingProps?: Partial<Props> | undefined) => (\n <ComponentWithProps\n bindProps={bindProps}\n component={component as ComponentType<Props>}\n overridingProps={overridingProps}\n />\n ));\n }\n\n const ComponentWithProps = memo(function ComponentWithProps({\n bindProps,\n component: Component,\n overridingProps\n }: {\n readonly bindProps?: Partial<Props> | ((props: Props) => Partial<Props>) | undefined;\n readonly component: ComponentType<Props>;\n readonly overridingProps?: Partial<Props> | undefined;\n }) {\n const { allowOverrideProps } = options;\n const { originalProps: renderCallbackProps } = useContext(RenderContext);\n\n if (overridingProps && !arePropsEqual(overridingProps, renderCallbackProps) && !allowOverrideProps) {\n console.warn('react-chain-of-responsibility: \"allowOverrideProps\" must be set to true to override props');\n }\n\n const props = Object.freeze(\n allowOverrideProps ? { ...renderCallbackProps, ...overridingProps } : { ...renderCallbackProps }\n );\n\n return <Component {...props} {...(typeof bindProps === 'function' ? bindProps(props) : bindProps)} />;\n });\n\n const useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props> = () => {\n const { enhancer } = useContext(BuildContext);\n\n return useCallback(\n (request, buildOptions = {}) => {\n const result =\n // Put the \"fallbackComponent\" as the last one in the chain.\n enhancer(() => {\n const { fallbackComponent } = buildOptions;\n\n if (!fallbackComponent) {\n console.warn(\n 'react-chain-of-responsibility: the request has fall through all middleware, set \"fallbackComponent\" as a catchall',\n request\n );\n\n // For clarity, we are returning `undefined` instead of `() => undefined`.\n return;\n }\n\n // `fallbackComponent` do not need `overridingProps` because it is the last one in the chain, it would not have the next() function.\n return reactComponent(fallbackComponent);\n })(request);\n\n return (\n result &&\n ((originalProps: Props) => (\n // This is render function, we cannot call any hooks here.\n <BuildRenderCallback originalProps={originalProps} render={result.render} />\n ))\n );\n },\n [enhancer]\n );\n };\n\n type BuildRenderCallbackProps = {\n readonly originalProps: Props;\n readonly render: () => ReactNode;\n };\n\n // Do not memoize <BuildRenderCallback>.\n // `bindProps` may have side effect and we want to be re-rendered to capture the side-effect.\n // To prevent wasted render, web devs should memoize it themselves.\n function BuildRenderCallback({ originalProps, render }: BuildRenderCallbackProps) {\n const context = useMemo<RenderContextType<Props>>(() => Object.freeze({ originalProps }), [originalProps]);\n\n return <RenderContext.Provider value={context}>{render()}</RenderContext.Provider>;\n }\n\n function ChainOfResponsibilityProvider({ children, init, middleware }: ProviderProps<Request, Props, Init>) {\n if (!Array.isArray(middleware) || middleware.some(middleware => typeof middleware !== 'function')) {\n throw new Error('react-chain-of-responsibility: \"middleware\" prop must be an array of functions');\n }\n\n // Remap the middleware, so all inputs/outputs are validated.\n const fortifiedMiddleware = useMemo(\n () =>\n Object.freeze(\n middleware.map<ComponentMiddleware<Request, Props, Init>>(fn => (init: Init) => {\n const enhancer = fn(init);\n\n return next => originalRequest => {\n // False positive: although we did not re-assign the variable from true, it was initialized as undefined.\n // eslint-disable-next-line prefer-const\n let hasReturned: boolean;\n\n const returnValue = enhancer(nextRequest => {\n if (hasReturned) {\n throw new Error(\n 'react-chain-of-responsibility: next() cannot be called after the function had returned synchronously'\n );\n }\n\n // We do not allow passing void/undefined to next() because it would be confusing whether to keep the original request or pass an undefined.\n !options.passModifiedRequest &&\n !Object.is(nextRequest, originalRequest) &&\n console.warn(\n 'react-chain-of-responsibility: next() must be called with the original request, otherwise, set \"options.passModifiedRequest\" to true to pass a different request object downstream'\n );\n\n return next(options.passModifiedRequest ? nextRequest : originalRequest);\n })(originalRequest);\n\n hasReturned = true;\n\n // Make sure the return value is built using our helper function for forward-compatibility reason.\n return returnValue && parse(componentHandlerResultSchema, returnValue);\n };\n })\n ),\n [middleware]\n );\n\n const { enhancer: parentEnhancer } = useContext(BuildContext);\n\n const enhancer = useMemo<ComponentEnhancer<Request, Props>>(\n () =>\n // We are reversing because it is easier to read:\n // - With reverse, [a, b, c] will become a(b(c(fn)))\n // - Without reverse, [a, b, c] will become c(b(a(fn)))\n applyMiddleware<ComponentHandlerResult<Props> | undefined, Request, Init>(\n ...[...fortifiedMiddleware, ...[() => parentEnhancer]]\n )(init as Init),\n [init, fortifiedMiddleware, parentEnhancer]\n );\n\n const contextValue = useMemo<BuildContextType<Request, Props>>(() => Object.freeze({ enhancer }), [enhancer]);\n\n return <BuildContext.Provider value={contextValue}>{children}</BuildContext.Provider>;\n }\n\n function ChainOfResponsibilityProxy({ fallbackComponent, request, ...props }: ProxyProps<Request, Props>) {\n const result = useBuildRenderCallback()(request, { fallbackComponent })?.(props as Props);\n\n return result ? <Fragment>{result}</Fragment> : null;\n }\n\n const MemoizedChainOfResponsibilityProvider =\n memo<ProviderProps<Request, Props, Init>>(ChainOfResponsibilityProvider);\n\n return Object.freeze({\n Provider: MemoizedChainOfResponsibilityProvider as typeof MemoizedChainOfResponsibilityProvider &\n InferenceHelper<Request, Props, Init>,\n Proxy: ChainOfResponsibilityProxy,\n reactComponent,\n useBuildRenderCallback\n\n // TODO: Consider adding back `asMiddleware`.\n });\n}\n\nexport default createChainOfResponsibility;\nexport {\n type ChainOfResponsibility,\n type ComponentEnhancer,\n type ComponentHandler,\n type ComponentHandlerResult,\n type ComponentMiddleware,\n type ComponentRenderer,\n type CreateChainOfResponsibilityOptions,\n type InferenceHelper,\n type InferInit,\n type InferMiddleware,\n type InferProps,\n type InferProviderProps,\n type InferProxyProps,\n type InferRequest,\n type ProviderProps,\n type ProxyProps,\n type ReactComponentHandlerResult,\n type UseBuildRenderCallback,\n type UseBuildRenderCallbackOptions\n};\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function arePropsEqual<T extends Record<string, any>>(x: T, y: T): boolean {\n if (Object.is(x, y)) {\n return true;\n }\n\n const mapOfX = new Map(Object.entries(x));\n const mapOfY = new Map(Object.entries(y));\n\n if (mapOfX.size !== mapOfY.size) {\n return false;\n }\n\n const keys = new Set([...mapOfX.keys(), ...mapOfY.keys()]);\n\n for (const key of keys) {\n if (!Object.is(mapOfX.get(key), mapOfY.get(key))) {\n return false;\n }\n }\n\n return true;\n}\n"],"mappings":"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","names":["React","ComponentWithProps","middleware","init","enhancer"]}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
} from "./chunk-TNTIZJJ5.mjs";
|
|
4
|
-
|
|
5
|
-
// src/createChainOfResponsibilityAsRenderCallback.tsx
|
|
1
|
+
// src/preview/createChainOfResponsibilityAsRenderCallback.tsx
|
|
2
|
+
import { applyMiddleware } from "handler-chain";
|
|
6
3
|
import React, {
|
|
7
4
|
createContext,
|
|
8
5
|
Fragment,
|
|
@@ -13,7 +10,7 @@ import React, {
|
|
|
13
10
|
} from "react";
|
|
14
11
|
import { custom, function_, object, parse, safeParse } from "valibot";
|
|
15
12
|
|
|
16
|
-
// src/private/arePropsEqual.ts
|
|
13
|
+
// src/preview/private/arePropsEqual.ts
|
|
17
14
|
function arePropsEqual(x, y) {
|
|
18
15
|
if (Object.is(x, y)) {
|
|
19
16
|
return true;
|
|
@@ -32,25 +29,15 @@ function arePropsEqual(x, y) {
|
|
|
32
29
|
return true;
|
|
33
30
|
}
|
|
34
31
|
|
|
35
|
-
// src/
|
|
36
|
-
import { useEffect, useRef } from "react";
|
|
37
|
-
var NOT_INITIALIZED = Symbol();
|
|
38
|
-
function useMemoValueWithEquality(factory, equalityFn) {
|
|
39
|
-
const prevRef = useRef(NOT_INITIALIZED);
|
|
40
|
-
const next = factory();
|
|
41
|
-
const current = prevRef.current !== NOT_INITIALIZED && equalityFn(prevRef.current, next) ? prevRef.current : next;
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
prevRef.current = current;
|
|
44
|
-
});
|
|
45
|
-
return current;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// src/createChainOfResponsibilityAsRenderCallback.tsx
|
|
32
|
+
// src/preview/createChainOfResponsibilityAsRenderCallback.tsx
|
|
49
33
|
var DO_NOT_CREATE_THIS_OBJECT_YOURSELF = Symbol();
|
|
50
|
-
var
|
|
34
|
+
var componentHandlerResultSchema = custom(
|
|
51
35
|
(value) => safeParse(object({ render: function_() }), value).success && !!value && typeof value === "object" && DO_NOT_CREATE_THIS_OBJECT_YOURSELF in value,
|
|
52
36
|
"react-chain-of-responsibility: middleware must return value constructed by reactComponent()"
|
|
53
37
|
);
|
|
38
|
+
function createComponentHandlerResult(render) {
|
|
39
|
+
return Object.freeze({ [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: void 0, render });
|
|
40
|
+
}
|
|
54
41
|
function createChainOfResponsibility(options = {}) {
|
|
55
42
|
options = Object.freeze({ ...options });
|
|
56
43
|
const BuildContext = createContext(
|
|
@@ -67,17 +54,14 @@ function createChainOfResponsibility(options = {}) {
|
|
|
67
54
|
})
|
|
68
55
|
);
|
|
69
56
|
function reactComponent(component, bindProps) {
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
)
|
|
80
|
-
});
|
|
57
|
+
return createComponentHandlerResult((overridingProps) => /* @__PURE__ */ React.createElement(
|
|
58
|
+
ComponentWithProps,
|
|
59
|
+
{
|
|
60
|
+
bindProps,
|
|
61
|
+
component,
|
|
62
|
+
overridingProps
|
|
63
|
+
}
|
|
64
|
+
));
|
|
81
65
|
}
|
|
82
66
|
const ComponentWithProps = memo(function ComponentWithProps2({
|
|
83
67
|
bindProps,
|
|
@@ -85,7 +69,7 @@ function createChainOfResponsibility(options = {}) {
|
|
|
85
69
|
overridingProps
|
|
86
70
|
}) {
|
|
87
71
|
const { allowOverrideProps } = options;
|
|
88
|
-
const { renderCallbackProps } = useContext(RenderContext);
|
|
72
|
+
const { originalProps: renderCallbackProps } = useContext(RenderContext);
|
|
89
73
|
if (overridingProps && !arePropsEqual(overridingProps, renderCallbackProps) && !allowOverrideProps) {
|
|
90
74
|
console.warn('react-chain-of-responsibility: "allowOverrideProps" must be set to true to override props');
|
|
91
75
|
}
|
|
@@ -109,29 +93,21 @@ function createChainOfResponsibility(options = {}) {
|
|
|
109
93
|
);
|
|
110
94
|
return;
|
|
111
95
|
}
|
|
112
|
-
return
|
|
113
|
-
// Mark fallback render callback as functor return value.
|
|
114
|
-
[DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: void 0,
|
|
115
|
-
render: () => (
|
|
116
|
-
// Currently, there are no ways to set `bindProps` to `fallbackComponent`.
|
|
117
|
-
// `fallbackComponent` do not need `overridingProps` because it is the last one in the chain, it would not have the next() function.
|
|
118
|
-
/* @__PURE__ */ React.createElement(ComponentWithProps, { component: fallbackComponent })
|
|
119
|
-
)
|
|
120
|
-
});
|
|
96
|
+
return reactComponent(fallbackComponent);
|
|
121
97
|
})(request)
|
|
122
98
|
);
|
|
123
|
-
return result && ((
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
[renderCallbackProps]
|
|
128
|
-
);
|
|
129
|
-
return /* @__PURE__ */ React.createElement(RenderContext.Provider, { value: context }, result.render());
|
|
130
|
-
});
|
|
99
|
+
return result && ((originalProps) => (
|
|
100
|
+
// This is render function, we cannot call any hooks here.
|
|
101
|
+
/* @__PURE__ */ React.createElement(BuildRenderCallback, { originalProps, render: result.render })
|
|
102
|
+
));
|
|
131
103
|
},
|
|
132
104
|
[enhancer]
|
|
133
105
|
);
|
|
134
106
|
};
|
|
107
|
+
function BuildRenderCallback({ originalProps, render }) {
|
|
108
|
+
const context = useMemo(() => Object.freeze({ originalProps }), [originalProps]);
|
|
109
|
+
return /* @__PURE__ */ React.createElement(RenderContext.Provider, { value: context }, render());
|
|
110
|
+
}
|
|
135
111
|
function ChainOfResponsibilityProvider({ children, init, middleware }) {
|
|
136
112
|
if (!Array.isArray(middleware) || middleware.some((middleware2) => typeof middleware2 !== "function")) {
|
|
137
113
|
throw new Error('react-chain-of-responsibility: "middleware" prop must be an array of functions');
|
|
@@ -154,7 +130,7 @@ function createChainOfResponsibility(options = {}) {
|
|
|
154
130
|
return next(options.passModifiedRequest ? nextRequest : originalRequest);
|
|
155
131
|
})(originalRequest);
|
|
156
132
|
hasReturned = true;
|
|
157
|
-
return returnValue && parse(
|
|
133
|
+
return returnValue && parse(componentHandlerResultSchema, returnValue);
|
|
158
134
|
};
|
|
159
135
|
})
|
|
160
136
|
),
|
|
@@ -167,7 +143,7 @@ function createChainOfResponsibility(options = {}) {
|
|
|
167
143
|
// - With reverse, [a, b, c] will become a(b(c(fn)))
|
|
168
144
|
// - Without reverse, [a, b, c] will become c(b(a(fn)))
|
|
169
145
|
applyMiddleware(
|
|
170
|
-
...[...fortifiedMiddleware, ...[() => parentEnhancer]]
|
|
146
|
+
...[...fortifiedMiddleware, ...[() => parentEnhancer]]
|
|
171
147
|
)(init)
|
|
172
148
|
),
|
|
173
149
|
[init, fortifiedMiddleware, parentEnhancer]
|
|
@@ -182,7 +158,7 @@ function createChainOfResponsibility(options = {}) {
|
|
|
182
158
|
const MemoizedChainOfResponsibilityProvider = memo(ChainOfResponsibilityProvider);
|
|
183
159
|
return Object.freeze({
|
|
184
160
|
Provider: MemoizedChainOfResponsibilityProvider,
|
|
185
|
-
Proxy:
|
|
161
|
+
Proxy: ChainOfResponsibilityProxy,
|
|
186
162
|
reactComponent,
|
|
187
163
|
useBuildRenderCallback
|
|
188
164
|
// TODO: Consider adding back `asMiddleware`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/createChainOfResponsibilityAsRenderCallback.tsx","../src/private/arePropsEqual.ts","../src/private/useMemoValueWithEquality.ts"],"sourcesContent":["import React, {\n createContext,\n Fragment,\n memo,\n useCallback,\n useContext,\n useMemo,\n type ComponentType,\n type PropsWithChildren,\n type ReactNode\n} from 'react';\nimport { custom, function_, object, parse, safeParse } from 'valibot';\n\nimport applyMiddleware from './private/applyMiddleware.ts';\nimport arePropsEqual from './private/arePropsEqual.ts';\nimport useMemoValueWithEquality from './private/useMemoValueWithEquality.ts';\n\n// TODO: Related to https://github.com/microsoft/TypeScript/issues/17002.\n// typescript@5.2.2 has a bug, Array.isArray() is a type predicate but only works with mutable array, not readonly array.\ndeclare global {\n interface ArrayConstructor {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n isArray(arg: any): arg is readonly any[];\n }\n}\n\ntype BaseProps = object;\n\ntype RenderCallback<Props extends BaseProps> = (props: Props) => ReactNode;\n\ntype CreateChainOfResponsibilityOptions = {\n /**\n * Allows one component to pass different set of props to its downstream component. Default is false.\n *\n * It is recommended to keep this settings as default to prevent newly added component from unexpectedly changing behavior of downstream components.\n */\n readonly allowOverrideProps?: boolean | undefined;\n\n /**\n * Allows a middleware to pass another request object when calling its next middleware. Default is false.\n *\n * It is recommended to keep this settings as default ot prevent newly added middleware from unexpectedly changing behavior of downstream middleware.\n *\n * To prevent upstream middleware from modifying the request, the request object should be set to be immutable through `Object.freeze`.\n */\n readonly passModifiedRequest?: boolean | undefined;\n};\n\ntype ChainOfResponsibility<Request, Props extends BaseProps, Init> = {\n readonly Provider: ComponentType<ProviderProps<Request, Props, Init>> & InferenceHelper<Request, Props, Init>;\n readonly Proxy: ComponentType<ProxyProps<Request, Props>>;\n readonly reactComponent: <P extends Props>(\n component: ComponentType<P>,\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n ) => ComponentFunctorReturnValue<Props>;\n readonly useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props>;\n};\n\nconst DO_NOT_CREATE_THIS_OBJECT_YOURSELF = Symbol();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst componentFunctorReturnValueSchema = custom<ComponentFunctorReturnValue<any>>(\n value =>\n safeParse(object({ render: function_() }), value).success &&\n !!value &&\n typeof value === 'object' &&\n DO_NOT_CREATE_THIS_OBJECT_YOURSELF in value,\n 'react-chain-of-responsibility: middleware must return value constructed by reactComponent()'\n);\n\ninterface ComponentFunctorReturnValue<Props extends BaseProps> {\n readonly [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined;\n readonly render: (overridingProps?: Partial<Props> | undefined) => ReactNode;\n}\n\ntype ComponentFunctor<Request, Props extends BaseProps> = (\n request: Request\n) => ComponentFunctorReturnValue<Props> | undefined;\n\ntype ComponentEnhancer<Request, Props extends BaseProps> = (\n next: ComponentFunctor<Request, Props>\n) => ComponentFunctor<Request, Props>;\n\ntype ComponentMiddleware<Request, Props extends BaseProps, Init = undefined> = (\n init: Init\n) => ComponentEnhancer<Request, Props>;\n\ntype UseBuildRenderCallbackOptions<Props> = {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n};\n\ninterface UseBuildRenderCallback<Request, Props extends BaseProps> {\n (request: Request, options?: undefined | UseBuildRenderCallbackOptions<Props>): RenderCallback<Props> | undefined;\n}\n\ntype BuildContextType<Request, Props extends BaseProps> = {\n readonly enhancer: ComponentEnhancer<Request, Props>;\n};\n\ntype RenderContextType<Props> = {\n readonly renderCallbackProps: Props;\n};\n\ntype ProviderProps<Request, Props extends BaseProps, Init> = PropsWithChildren<{\n readonly middleware: readonly ComponentMiddleware<Request, Props, Init>[];\n}> &\n (Init extends never | void\n ? { readonly init?: undefined }\n : Init extends undefined | void\n ? { readonly init?: Init }\n : { readonly init: Init });\n\ntype ProxyProps<Request, Props extends BaseProps> = Props & {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n readonly request: Request;\n};\n\ntype InferenceHelper<Request, Props extends BaseProps, Init> = {\n readonly '~types': {\n readonly component: ComponentType<Props>;\n readonly init: Init;\n readonly middleware: ComponentMiddleware<Request, Props, Init>;\n readonly props: Props;\n readonly proxyProps: ProxyProps<Request, Props>;\n readonly request: Request;\n };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferComponent<T extends InferenceHelper<any, any, any>> = T['~types']['component'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferInit<T extends InferenceHelper<any, any, any>> = T['~types']['init'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferMiddleware<T extends InferenceHelper<any, any, any>> = T['~types']['middleware'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProps<T extends InferenceHelper<any, any, any>> = T['~types']['props'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProxyProps<T extends InferenceHelper<any, any, any>> = T['~types']['proxyProps'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferRequest<T extends InferenceHelper<any, any, any>> = T['~types']['request'];\n\nfunction createChainOfResponsibility<\n Request = void,\n Props extends BaseProps = { readonly children?: never },\n Init = void\n>(options: CreateChainOfResponsibilityOptions = {}): ChainOfResponsibility<Request, Props, Init> {\n // Freeze options to prevent accidental change.\n options = Object.freeze({ ...options });\n\n const BuildContext = createContext<BuildContextType<Request, Props>>(\n Object.freeze({ enhancer: next => request => next(request) })\n );\n\n const RenderContext = createContext<RenderContextType<Props>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new Proxy({} as any, {\n get() {\n // The following is assertion, there is no way to hit this line.\n /* istanbul ignore next */\n throw new Error(\n 'react-chain-of-responsibility: this hook cannot be used outside of <Proxy> and useBuildRenderCallback()'\n );\n }\n })\n );\n\n function reactComponent<P extends Props>(\n component: ComponentType<P>,\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n ): ComponentFunctorReturnValue<Props> {\n return Object.freeze({\n [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined,\n render: (overridingProps?: Partial<Props> | undefined) => (\n <ComponentWithProps\n bindProps={bindProps}\n component={component as ComponentType<Props>}\n overridingProps={overridingProps}\n />\n )\n });\n }\n\n const ComponentWithProps = memo(function ComponentWithProps({\n bindProps,\n component: Component,\n overridingProps\n }: {\n readonly bindProps?: Partial<Props> | ((props: Props) => Partial<Props>) | undefined;\n readonly component: ComponentType<Props>;\n readonly overridingProps?: Partial<Props> | undefined;\n }) {\n const { allowOverrideProps } = options;\n const { renderCallbackProps } = useContext(RenderContext);\n\n if (overridingProps && !arePropsEqual(overridingProps, renderCallbackProps) && !allowOverrideProps) {\n console.warn('react-chain-of-responsibility: \"allowOverrideProps\" must be set to true to override props');\n }\n\n const props = Object.freeze(\n allowOverrideProps ? { ...renderCallbackProps, ...overridingProps } : { ...renderCallbackProps }\n );\n\n return <Component {...props} {...(typeof bindProps === 'function' ? bindProps(props) : bindProps)} />;\n });\n\n const useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props> = () => {\n const { enhancer } = useContext(BuildContext);\n\n return useCallback(\n (request, buildOptions = {}) => {\n const result =\n // Put the \"fallbackComponent\" as the last one in the chain.\n enhancer(() => {\n const { fallbackComponent } = buildOptions;\n\n if (!fallbackComponent) {\n console.warn(\n 'react-chain-of-responsibility: the request has fall through all middleware, set \"fallbackComponent\" as a catchall',\n request\n );\n\n // For clarity, we are returning `undefined` instead of `() => undefined`.\n return;\n }\n\n return Object.freeze({\n // Mark fallback render callback as functor return value.\n [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined,\n render: () => (\n // Currently, there are no ways to set `bindProps` to `fallbackComponent`.\n // `fallbackComponent` do not need `overridingProps` because it is the last one in the chain, it would not have the next() function.\n <ComponentWithProps component={fallbackComponent} />\n )\n });\n })(request);\n\n return (\n result &&\n ((props: Props) => {\n const renderCallbackProps = useMemoValueWithEquality<Props>(() => props, arePropsEqual);\n\n const context = useMemo<RenderContextType<Props>>(\n () => Object.freeze({ renderCallbackProps }),\n [renderCallbackProps]\n );\n\n return <RenderContext.Provider value={context}>{result.render()}</RenderContext.Provider>;\n })\n );\n },\n [enhancer]\n );\n };\n\n function ChainOfResponsibilityProvider({ children, init, middleware }: ProviderProps<Request, Props, Init>) {\n if (!Array.isArray(middleware) || middleware.some(middleware => typeof middleware !== 'function')) {\n throw new Error('react-chain-of-responsibility: \"middleware\" prop must be an array of functions');\n }\n\n // Remap the middleware, so all inputs/outputs are validated.\n const fortifiedMiddleware = useMemo(\n () =>\n Object.freeze(\n middleware.map<ComponentMiddleware<Request, Props, Init>>(fn => (init: Init) => {\n const enhancer = fn(init);\n\n return next => originalRequest => {\n // False positive: although we did not re-assign the variable from true, it was initialized as undefined.\n // eslint-disable-next-line prefer-const\n let hasReturned: boolean;\n\n const returnValue = enhancer(nextRequest => {\n if (hasReturned) {\n throw new Error(\n 'react-chain-of-responsibility: next() cannot be called after the function had returned synchronously'\n );\n }\n\n // We do not allow passing void/undefined to next() because it would be confusing whether to keep the original request or pass an undefined.\n !options.passModifiedRequest &&\n !Object.is(nextRequest, originalRequest) &&\n console.warn(\n 'react-chain-of-responsibility: next() must be called with the original request, otherwise, set \"options.passModifiedRequest\" to true to pass a different request object downstream'\n );\n\n return next(options.passModifiedRequest ? nextRequest : originalRequest);\n })(originalRequest);\n\n hasReturned = true;\n\n // Make sure the return value is built using our helper function for forward-compatibility reason.\n return returnValue && parse(componentFunctorReturnValueSchema, returnValue);\n };\n })\n ),\n [middleware]\n );\n\n const { enhancer: parentEnhancer } = useContext(BuildContext);\n\n const enhancer = useMemo<ComponentEnhancer<Request, Props>>(\n () =>\n // We are reversing because it is easier to read:\n // - With reverse, [a, b, c] will become a(b(c(fn)))\n // - Without reverse, [a, b, c] will become c(b(a(fn)))\n applyMiddleware<[Request], ComponentFunctorReturnValue<Props> | undefined, [Init]>(\n ...[...fortifiedMiddleware, ...[() => parentEnhancer]].reverse()\n )(init as Init),\n [init, fortifiedMiddleware, parentEnhancer]\n );\n\n const contextValue = useMemo<BuildContextType<Request, Props>>(() => Object.freeze({ enhancer }), [enhancer]);\n\n return <BuildContext.Provider value={contextValue}>{children}</BuildContext.Provider>;\n }\n\n function ChainOfResponsibilityProxy({ fallbackComponent, request, ...props }: ProxyProps<Request, Props>) {\n const result = useBuildRenderCallback()(request, { fallbackComponent })?.(props as Props);\n\n return result ? <Fragment>{result}</Fragment> : null;\n }\n\n const MemoizedChainOfResponsibilityProvider =\n memo<ProviderProps<Request, Props, Init>>(ChainOfResponsibilityProvider);\n\n return Object.freeze({\n Provider: MemoizedChainOfResponsibilityProvider as typeof MemoizedChainOfResponsibilityProvider &\n InferenceHelper<Request, Props, Init>,\n Proxy: memo<ProxyProps<Request, Props>>(ChainOfResponsibilityProxy),\n reactComponent,\n useBuildRenderCallback\n\n // TODO: Consider adding back `asMiddleware`.\n });\n}\n\nexport default createChainOfResponsibility;\nexport {\n type ChainOfResponsibility,\n type CreateChainOfResponsibilityOptions,\n type InferComponent,\n type InferInit,\n type InferMiddleware,\n type InferProps,\n type InferProxyProps,\n type InferRequest,\n type UseBuildRenderCallback\n};\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function arePropsEqual<T extends Record<string, any>>(x: T, y: T): boolean {\n if (Object.is(x, y)) {\n return true;\n }\n\n const mapOfX = new Map(Object.entries(x));\n const mapOfY = new Map(Object.entries(y));\n\n if (mapOfX.size !== mapOfY.size) {\n return false;\n }\n\n const keys = new Set([...mapOfX.keys(), ...mapOfY.keys()]);\n\n for (const key of keys) {\n if (!Object.is(mapOfX.get(key), mapOfY.get(key))) {\n return false;\n }\n }\n\n return true;\n}\n","import { useEffect, useRef } from 'react';\n\nconst NOT_INITIALIZED = Symbol();\n\nexport default function useMemoValueWithEquality<T>(factory: () => T, equalityFn: (x: T, y: T) => boolean): T {\n const prevRef = useRef<T | typeof NOT_INITIALIZED>(NOT_INITIALIZED);\n const next: T = factory();\n const current: T = prevRef.current !== NOT_INITIALIZED && equalityFn(prevRef.current, next) ? prevRef.current : next;\n\n useEffect(() => {\n prevRef.current = current;\n });\n\n return current;\n}\n"],"mappings":"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","names":["ComponentWithProps","middleware","init","enhancer"]}
|
|
1
|
+
{"version":3,"sources":["../src/preview/createChainOfResponsibilityAsRenderCallback.tsx","../src/preview/private/arePropsEqual.ts"],"sourcesContent":["import { applyMiddleware } from 'handler-chain';\nimport React, {\n createContext,\n Fragment,\n memo,\n useCallback,\n useContext,\n useMemo,\n type ComponentType,\n type PropsWithChildren,\n type ReactNode\n} from 'react';\nimport { custom, function_, object, parse, safeParse } from 'valibot';\n\nimport arePropsEqual from './private/arePropsEqual.ts';\n\n// TODO: Related to https://github.com/microsoft/TypeScript/issues/17002.\n// typescript@5.2.2 has a bug, Array.isArray() is a type predicate but only works with mutable array, not readonly array.\ndeclare global {\n interface ArrayConstructor {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n isArray(arg: any): arg is readonly any[];\n }\n}\n\ntype BaseProps = object;\n\ntype CreateChainOfResponsibilityOptions = {\n /**\n * Allows one component to pass different set of props to its downstream component. Default is false.\n *\n * It is recommended to keep this settings as default to prevent newly added component from unexpectedly changing behavior of downstream components.\n */\n readonly allowOverrideProps?: boolean | undefined;\n\n /**\n * Allows a middleware to pass another request object when calling its next middleware. Default is false.\n *\n * It is recommended to keep this settings as default ot prevent newly added middleware from unexpectedly changing behavior of downstream middleware.\n *\n * To prevent upstream middleware from modifying the request, the request object should be set to be immutable through `Object.freeze`.\n */\n readonly passModifiedRequest?: boolean | undefined;\n};\n\ntype ChainOfResponsibility<Request, Props extends BaseProps, Init> = {\n readonly Provider: ComponentType<ProviderProps<Request, Props, Init>> & InferenceHelper<Request, Props, Init>;\n readonly Proxy: ComponentType<ProxyProps<Request, Props>>;\n readonly reactComponent: ReactComponentHandlerResult<Props>;\n readonly useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props>;\n};\n\n// TODO: Maybe this one should be local.\n// Verify that reactComponent() from an instance of CoR should throw error when used in another instance of CoR.\nconst DO_NOT_CREATE_THIS_OBJECT_YOURSELF = Symbol();\n\ntype ComponentRenderer<Props> = (props: Props) => ReactNode;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst componentHandlerResultSchema = custom<ComponentHandlerResult<any>>(\n value =>\n safeParse(object({ render: function_() }), value).success &&\n !!value &&\n typeof value === 'object' &&\n DO_NOT_CREATE_THIS_OBJECT_YOURSELF in value,\n 'react-chain-of-responsibility: middleware must return value constructed by reactComponent()'\n);\n\ninterface ComponentHandlerResult<Props extends BaseProps> {\n readonly [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined;\n readonly render: (overridingProps?: Partial<Props> | undefined) => ReactNode;\n}\n\ntype ComponentHandler<Request, Props extends BaseProps> = (\n request: Request\n) => ComponentHandlerResult<Props> | undefined;\n\ntype ComponentEnhancer<Request, Props extends BaseProps> = (\n next: ComponentHandler<Request, Props>\n) => ComponentHandler<Request, Props>;\n\ntype ComponentMiddleware<Request, Props extends BaseProps, Init = undefined> = (\n init: Init\n) => ComponentEnhancer<Request, Props>;\n\ntype ReactComponentHandlerResult<Props extends object> = <P extends Props>(\n component: ComponentType<P>,\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n) => ComponentHandlerResult<Props>;\n\ntype UseBuildRenderCallbackOptions<Props> = {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n};\n\ninterface UseBuildRenderCallback<Request, Props extends BaseProps> {\n (request: Request, options?: undefined | UseBuildRenderCallbackOptions<Props>): ComponentRenderer<Props> | undefined;\n}\n\ntype BuildContextType<Request, Props extends BaseProps> = {\n readonly enhancer: ComponentEnhancer<Request, Props>;\n};\n\ntype RenderContextType<Props> = {\n readonly originalProps: Props;\n};\n\ntype ProviderProps<Request, Props extends BaseProps, Init> = PropsWithChildren<{\n readonly middleware: readonly ComponentMiddleware<Request, Props, Init>[];\n}> &\n (Init extends never | void\n ? { readonly init?: undefined }\n : Init extends undefined | void\n ? { readonly init?: Init }\n : { readonly init: Init });\n\ntype ProxyProps<Request, Props extends BaseProps> = Props & {\n readonly fallbackComponent?: ComponentType<Props> | undefined;\n readonly request: Request;\n};\n\ntype InferenceHelper<Request, Props extends BaseProps, Init> = {\n readonly '~types': {\n readonly init: Init;\n readonly middleware: ComponentMiddleware<Request, Props, Init>;\n readonly props: Props;\n readonly proxyProps: ProxyProps<Request, Props>;\n readonly providerProps: ProviderProps<Request, Props, Init>;\n readonly request: Request;\n };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferInit<T extends InferenceHelper<any, any, any>> = T['~types']['init'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferMiddleware<T extends InferenceHelper<any, any, any>> = T['~types']['middleware'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProps<T extends InferenceHelper<any, any, any>> = T['~types']['props'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProxyProps<T extends InferenceHelper<any, any, any>> = T['~types']['proxyProps'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferProviderProps<T extends InferenceHelper<any, any, any>> = T['~types']['providerProps'];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferRequest<T extends InferenceHelper<any, any, any>> = T['~types']['request'];\n\nfunction createComponentHandlerResult<Props extends BaseProps>(\n render: (overridingProps?: Partial<Props> | undefined) => ReactNode\n): ComponentHandlerResult<Props> {\n return Object.freeze({ [DO_NOT_CREATE_THIS_OBJECT_YOURSELF]: undefined, render });\n}\n\nfunction createChainOfResponsibility<\n Request = void,\n Props extends BaseProps = { readonly children?: never },\n Init = void\n>(options: CreateChainOfResponsibilityOptions = {}): ChainOfResponsibility<Request, Props, Init> {\n // Freeze options to prevent accidental change.\n options = Object.freeze({ ...options });\n\n const BuildContext = createContext<BuildContextType<Request, Props>>(\n Object.freeze({ enhancer: next => request => next(request) })\n );\n\n const RenderContext = createContext<RenderContextType<Props>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new Proxy({} as any, {\n get() {\n // The following is assertion, there is no way to hit this line.\n /* istanbul ignore next */\n throw new Error(\n 'react-chain-of-responsibility: this hook cannot be used outside of <Proxy> and useBuildRenderCallback()'\n );\n }\n })\n );\n\n function reactComponent<P extends Props>(\n component: ComponentType<P>,\n // For `bindProps` of type function, do not do side-effect in it, it may not be always called in all scenarios.\n bindProps?:\n | (Partial<Props> & Omit<P, keyof Props>)\n | ((props: Props) => Partial<Props> & Omit<P, keyof Props>)\n | undefined\n ): ComponentHandlerResult<Props> {\n return createComponentHandlerResult((overridingProps?: Partial<Props> | undefined) => (\n <ComponentWithProps\n bindProps={bindProps}\n component={component as ComponentType<Props>}\n overridingProps={overridingProps}\n />\n ));\n }\n\n const ComponentWithProps = memo(function ComponentWithProps({\n bindProps,\n component: Component,\n overridingProps\n }: {\n readonly bindProps?: Partial<Props> | ((props: Props) => Partial<Props>) | undefined;\n readonly component: ComponentType<Props>;\n readonly overridingProps?: Partial<Props> | undefined;\n }) {\n const { allowOverrideProps } = options;\n const { originalProps: renderCallbackProps } = useContext(RenderContext);\n\n if (overridingProps && !arePropsEqual(overridingProps, renderCallbackProps) && !allowOverrideProps) {\n console.warn('react-chain-of-responsibility: \"allowOverrideProps\" must be set to true to override props');\n }\n\n const props = Object.freeze(\n allowOverrideProps ? { ...renderCallbackProps, ...overridingProps } : { ...renderCallbackProps }\n );\n\n return <Component {...props} {...(typeof bindProps === 'function' ? bindProps(props) : bindProps)} />;\n });\n\n const useBuildRenderCallback: () => UseBuildRenderCallback<Request, Props> = () => {\n const { enhancer } = useContext(BuildContext);\n\n return useCallback(\n (request, buildOptions = {}) => {\n const result =\n // Put the \"fallbackComponent\" as the last one in the chain.\n enhancer(() => {\n const { fallbackComponent } = buildOptions;\n\n if (!fallbackComponent) {\n console.warn(\n 'react-chain-of-responsibility: the request has fall through all middleware, set \"fallbackComponent\" as a catchall',\n request\n );\n\n // For clarity, we are returning `undefined` instead of `() => undefined`.\n return;\n }\n\n // `fallbackComponent` do not need `overridingProps` because it is the last one in the chain, it would not have the next() function.\n return reactComponent(fallbackComponent);\n })(request);\n\n return (\n result &&\n ((originalProps: Props) => (\n // This is render function, we cannot call any hooks here.\n <BuildRenderCallback originalProps={originalProps} render={result.render} />\n ))\n );\n },\n [enhancer]\n );\n };\n\n type BuildRenderCallbackProps = {\n readonly originalProps: Props;\n readonly render: () => ReactNode;\n };\n\n // Do not memoize <BuildRenderCallback>.\n // `bindProps` may have side effect and we want to be re-rendered to capture the side-effect.\n // To prevent wasted render, web devs should memoize it themselves.\n function BuildRenderCallback({ originalProps, render }: BuildRenderCallbackProps) {\n const context = useMemo<RenderContextType<Props>>(() => Object.freeze({ originalProps }), [originalProps]);\n\n return <RenderContext.Provider value={context}>{render()}</RenderContext.Provider>;\n }\n\n function ChainOfResponsibilityProvider({ children, init, middleware }: ProviderProps<Request, Props, Init>) {\n if (!Array.isArray(middleware) || middleware.some(middleware => typeof middleware !== 'function')) {\n throw new Error('react-chain-of-responsibility: \"middleware\" prop must be an array of functions');\n }\n\n // Remap the middleware, so all inputs/outputs are validated.\n const fortifiedMiddleware = useMemo(\n () =>\n Object.freeze(\n middleware.map<ComponentMiddleware<Request, Props, Init>>(fn => (init: Init) => {\n const enhancer = fn(init);\n\n return next => originalRequest => {\n // False positive: although we did not re-assign the variable from true, it was initialized as undefined.\n // eslint-disable-next-line prefer-const\n let hasReturned: boolean;\n\n const returnValue = enhancer(nextRequest => {\n if (hasReturned) {\n throw new Error(\n 'react-chain-of-responsibility: next() cannot be called after the function had returned synchronously'\n );\n }\n\n // We do not allow passing void/undefined to next() because it would be confusing whether to keep the original request or pass an undefined.\n !options.passModifiedRequest &&\n !Object.is(nextRequest, originalRequest) &&\n console.warn(\n 'react-chain-of-responsibility: next() must be called with the original request, otherwise, set \"options.passModifiedRequest\" to true to pass a different request object downstream'\n );\n\n return next(options.passModifiedRequest ? nextRequest : originalRequest);\n })(originalRequest);\n\n hasReturned = true;\n\n // Make sure the return value is built using our helper function for forward-compatibility reason.\n return returnValue && parse(componentHandlerResultSchema, returnValue);\n };\n })\n ),\n [middleware]\n );\n\n const { enhancer: parentEnhancer } = useContext(BuildContext);\n\n const enhancer = useMemo<ComponentEnhancer<Request, Props>>(\n () =>\n // We are reversing because it is easier to read:\n // - With reverse, [a, b, c] will become a(b(c(fn)))\n // - Without reverse, [a, b, c] will become c(b(a(fn)))\n applyMiddleware<ComponentHandlerResult<Props> | undefined, Request, Init>(\n ...[...fortifiedMiddleware, ...[() => parentEnhancer]]\n )(init as Init),\n [init, fortifiedMiddleware, parentEnhancer]\n );\n\n const contextValue = useMemo<BuildContextType<Request, Props>>(() => Object.freeze({ enhancer }), [enhancer]);\n\n return <BuildContext.Provider value={contextValue}>{children}</BuildContext.Provider>;\n }\n\n function ChainOfResponsibilityProxy({ fallbackComponent, request, ...props }: ProxyProps<Request, Props>) {\n const result = useBuildRenderCallback()(request, { fallbackComponent })?.(props as Props);\n\n return result ? <Fragment>{result}</Fragment> : null;\n }\n\n const MemoizedChainOfResponsibilityProvider =\n memo<ProviderProps<Request, Props, Init>>(ChainOfResponsibilityProvider);\n\n return Object.freeze({\n Provider: MemoizedChainOfResponsibilityProvider as typeof MemoizedChainOfResponsibilityProvider &\n InferenceHelper<Request, Props, Init>,\n Proxy: ChainOfResponsibilityProxy,\n reactComponent,\n useBuildRenderCallback\n\n // TODO: Consider adding back `asMiddleware`.\n });\n}\n\nexport default createChainOfResponsibility;\nexport {\n type ChainOfResponsibility,\n type ComponentEnhancer,\n type ComponentHandler,\n type ComponentHandlerResult,\n type ComponentMiddleware,\n type ComponentRenderer,\n type CreateChainOfResponsibilityOptions,\n type InferenceHelper,\n type InferInit,\n type InferMiddleware,\n type InferProps,\n type InferProviderProps,\n type InferProxyProps,\n type InferRequest,\n type ProviderProps,\n type ProxyProps,\n type ReactComponentHandlerResult,\n type UseBuildRenderCallback,\n type UseBuildRenderCallbackOptions\n};\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function arePropsEqual<T extends Record<string, any>>(x: T, y: T): boolean {\n if (Object.is(x, y)) {\n return true;\n }\n\n const mapOfX = new Map(Object.entries(x));\n const mapOfY = new Map(Object.entries(y));\n\n if (mapOfX.size !== mapOfY.size) {\n return false;\n }\n\n const keys = new Set([...mapOfX.keys(), ...mapOfY.keys()]);\n\n for (const key of keys) {\n if (!Object.is(mapOfX.get(key), mapOfY.get(key))) {\n return false;\n }\n }\n\n return true;\n}\n"],"mappings":"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","names":["ComponentWithProps","middleware","init","enhancer"]}
|