@elementor/locations 4.3.0-1042 → 4.3.0-1044
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/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -1
- package/src/injections.tsx +4 -0
package/dist/index.d.mts
CHANGED
|
@@ -88,5 +88,6 @@ declare function createLocation<TProps extends object = AnyProps>(): Location<TP
|
|
|
88
88
|
declare function createReplaceableLocation<TProps extends object = AnyProps>(): ReplaceableLocation<TProps>;
|
|
89
89
|
|
|
90
90
|
declare function flushAllInjections(): void;
|
|
91
|
+
declare function registerFlushInjections(flush: () => void): void;
|
|
91
92
|
|
|
92
|
-
export { type AnyProps, type Id, type InjectArgs, type InjectedComponent, type Injection, type Location, type Priority, type ReplaceableInjectArgs, type ReplaceableInjection, type ReplaceableLocation, flushAllInjections as __flushAllInjections, createLocation, createReplaceableLocation };
|
|
93
|
+
export { type AnyProps, type Id, type InjectArgs, type InjectedComponent, type Injection, type Location, type Priority, type ReplaceableInjectArgs, type ReplaceableInjection, type ReplaceableLocation, flushAllInjections as __flushAllInjections, registerFlushInjections as __registerFlushInjections, createLocation, createReplaceableLocation };
|
package/dist/index.d.ts
CHANGED
|
@@ -88,5 +88,6 @@ declare function createLocation<TProps extends object = AnyProps>(): Location<TP
|
|
|
88
88
|
declare function createReplaceableLocation<TProps extends object = AnyProps>(): ReplaceableLocation<TProps>;
|
|
89
89
|
|
|
90
90
|
declare function flushAllInjections(): void;
|
|
91
|
+
declare function registerFlushInjections(flush: () => void): void;
|
|
91
92
|
|
|
92
|
-
export { type AnyProps, type Id, type InjectArgs, type InjectedComponent, type Injection, type Location, type Priority, type ReplaceableInjectArgs, type ReplaceableInjection, type ReplaceableLocation, flushAllInjections as __flushAllInjections, createLocation, createReplaceableLocation };
|
|
93
|
+
export { type AnyProps, type Id, type InjectArgs, type InjectedComponent, type Injection, type Location, type Priority, type ReplaceableInjectArgs, type ReplaceableInjection, type ReplaceableLocation, flushAllInjections as __flushAllInjections, registerFlushInjections as __registerFlushInjections, createLocation, createReplaceableLocation };
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
__flushAllInjections: () => flushAllInjections,
|
|
34
|
+
__registerFlushInjections: () => registerFlushInjections,
|
|
34
35
|
createLocation: () => createLocation,
|
|
35
36
|
createReplaceableLocation: () => createReplaceableLocation
|
|
36
37
|
});
|
|
@@ -75,6 +76,9 @@ var flushInjectionsFns = [];
|
|
|
75
76
|
function flushAllInjections() {
|
|
76
77
|
flushInjectionsFns.forEach((flush) => flush());
|
|
77
78
|
}
|
|
79
|
+
function registerFlushInjections(flush) {
|
|
80
|
+
flushInjectionsFns.push(flush);
|
|
81
|
+
}
|
|
78
82
|
function createSubscription() {
|
|
79
83
|
const listeners = /* @__PURE__ */ new Set();
|
|
80
84
|
return {
|
|
@@ -191,6 +195,7 @@ function createRegister(injections, notify) {
|
|
|
191
195
|
// Annotate the CommonJS export names for ESM import in node:
|
|
192
196
|
0 && (module.exports = {
|
|
193
197
|
__flushAllInjections,
|
|
198
|
+
__registerFlushInjections,
|
|
194
199
|
createLocation,
|
|
195
200
|
createReplaceableLocation
|
|
196
201
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/create-location.tsx","../src/injections.tsx","../src/components/injected-component-wrapper.tsx","../src/components/error-boundary.tsx","../src/create-replaceable-location.tsx"],"sourcesContent":["export * from './types';\n\nexport { createLocation } from './create-location';\nexport { createReplaceableLocation } from './create-replaceable-location';\nexport { flushAllInjections as __flushAllInjections } from './injections';\n","import * as React from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport { type AnyProps, type Id, type InjectArgs, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport function createLocation< TProps extends object = AnyProps >(): Location< TProps > {\n\tconst injections: InjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createSlot( useInjections );\n\tconst inject = createInject( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tinject,\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tSlot,\n\t};\n}\n\nfunction createSlot< TProps extends object = AnyProps >( useInjections: Location< TProps >[ 'useInjections' ] ) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ injections.map( ( { id, component: Component } ) => (\n\t\t\t\t\t<Component { ...props } key={ id } />\n\t\t\t\t) ) }\n\t\t\t</>\n\t\t);\n\t};\n}\n\nfunction createInject< TProps extends object = AnyProps >( injections: InjectionsMap< TProps >, notify: () => void ) {\n\treturn ( { component, id, options = {} }: InjectArgs< TProps > ) => {\n\t\tif ( injections.has( id ) && ! options?.overwrite ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t`An injection with the id \"${ id }\" already exists. Did you mean to use \"options.overwrite\"?`\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n","import * as React from 'react';\nimport { useSyncExternalStore } from 'react';\n\nimport InjectedComponentWrapper from './components/injected-component-wrapper';\nimport { type AnyProps, type Id, type InjectedComponent, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport const DEFAULT_PRIORITY = 10;\n\n// Allow flushing all injections at once, for testing purposes.\nexport const flushInjectionsFns: ( () => void )[] = [];\n\nexport function flushAllInjections() {\n\tflushInjectionsFns.forEach( ( flush ) => flush() );\n}\n\nexport type Subscribe = ( listener: () => void ) => () => void;\n\nexport function createSubscription() {\n\tconst listeners = new Set< () => void >();\n\n\treturn {\n\t\tsubscribe: ( listener: () => void ) => {\n\t\t\tlisteners.add( listener );\n\n\t\t\treturn () => listeners.delete( listener );\n\t\t},\n\t\tnotify: () => listeners.forEach( ( listener ) => listener() ),\n\t};\n}\n\nexport function createGetInjections< TProps extends object = AnyProps >( injections: InjectionsMap< TProps > ) {\n\treturn () => [ ...injections.values() ].sort( ( a, b ) => a.priority - b.priority );\n}\n\n// Injections registered after the `Slot` has already mounted (e.g. by an external plugin's\n// script that loads after the editor has rendered) must still be reflected in the UI, so the\n// snapshot is invalidated and re-read whenever `notify()` is called.\nexport function createUseInjections< TProps extends object = AnyProps >(\n\tgetInjections: Location< TProps >[ 'getInjections' ],\n\tsubscribe: Subscribe\n) {\n\tlet snapshot: ReturnType< Location< TProps >[ 'getInjections' ] > | null = null;\n\n\tsubscribe( () => {\n\t\tsnapshot = null;\n\t} );\n\n\tconst getSnapshot = () => {\n\t\tif ( ! snapshot ) {\n\t\t\tsnapshot = getInjections();\n\t\t}\n\n\t\treturn snapshot;\n\t};\n\n\treturn () => useSyncExternalStore( subscribe, getSnapshot );\n}\n\nexport function wrapInjectedComponent< TProps extends object = AnyProps >( Component: InjectedComponent< TProps > ) {\n\treturn ( props: TProps ) => (\n\t\t<InjectedComponentWrapper>\n\t\t\t<Component { ...props } />\n\t\t</InjectedComponentWrapper>\n\t);\n}\n","import * as React from 'react';\nimport { type ReactNode, Suspense } from 'react';\n\nimport ErrorBoundary from './error-boundary';\n\nexport default function InjectedComponentWrapper( { children }: { children: ReactNode } ) {\n\treturn (\n\t\t<ErrorBoundary fallback={ null }>\n\t\t\t<Suspense fallback={ null }>{ children }</Suspense>\n\t\t</ErrorBoundary>\n\t);\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n\tchildren?: ReactNode;\n\tfallback: ReactNode;\n}\n\ninterface State {\n\thasError: boolean;\n}\n\nexport default class ErrorBoundary extends Component< Props, State > {\n\tpublic state: State = {\n\t\thasError: false,\n\t};\n\n\tpublic static getDerivedStateFromError(): State {\n\t\t// Update state so the next render will show the fallback UI.\n\t\treturn { hasError: true };\n\t}\n\n\tpublic render() {\n\t\tif ( this.state.hasError ) {\n\t\t\treturn this.props.fallback;\n\t\t}\n\n\t\treturn this.props.children;\n\t}\n}\n","import * as React from 'react';\nimport { type PropsWithChildren } from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport {\n\ttype AnyProps,\n\ttype Id,\n\ttype ReplaceableInjectArgs,\n\ttype ReplaceableInjection,\n\ttype ReplaceableLocation,\n} from './types';\n\ntype ReplaceableInjectionsMap< TProps extends object = AnyProps > = Map< Id, ReplaceableInjection< TProps > >;\n\nexport function createReplaceableLocation< TProps extends object = AnyProps >(): ReplaceableLocation< TProps > {\n\tconst injections: ReplaceableInjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createReplaceable( useInjections );\n\tconst inject = createRegister( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tinject,\n\t\tSlot,\n\t};\n}\n\nfunction createReplaceable< TProps extends PropsWithChildren< object > = AnyProps >(\n\tuseInjections: ReplaceableLocation< TProps >[ 'useInjections' ]\n) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\tconst { component: Component } = injections.find( ( { condition } ) => condition?.( props ) ) ?? {};\n\n\t\tif ( ! Component ) {\n\t\t\treturn props.children;\n\t\t}\n\n\t\treturn <Component { ...props } />;\n\t};\n}\n\nfunction createRegister< TProps extends object = AnyProps >(\n\tinjections: ReplaceableInjectionsMap< TProps >,\n\tnotify: () => void\n) {\n\treturn ( { component, id, condition = () => true, options = {} }: ReplaceableInjectArgs< TProps > ) => {\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tcondition,\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n"],"mappings":"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","names":["React","React","import_react","import_react","Component","Component","React","Component"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/create-location.tsx","../src/injections.tsx","../src/components/injected-component-wrapper.tsx","../src/components/error-boundary.tsx","../src/create-replaceable-location.tsx"],"sourcesContent":["export * from './types';\n\nexport { createLocation } from './create-location';\nexport { createReplaceableLocation } from './create-replaceable-location';\nexport {\n\tflushAllInjections as __flushAllInjections,\n\tregisterFlushInjections as __registerFlushInjections,\n} from './injections';\n","import * as React from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport { type AnyProps, type Id, type InjectArgs, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport function createLocation< TProps extends object = AnyProps >(): Location< TProps > {\n\tconst injections: InjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createSlot( useInjections );\n\tconst inject = createInject( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tinject,\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tSlot,\n\t};\n}\n\nfunction createSlot< TProps extends object = AnyProps >( useInjections: Location< TProps >[ 'useInjections' ] ) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ injections.map( ( { id, component: Component } ) => (\n\t\t\t\t\t<Component { ...props } key={ id } />\n\t\t\t\t) ) }\n\t\t\t</>\n\t\t);\n\t};\n}\n\nfunction createInject< TProps extends object = AnyProps >( injections: InjectionsMap< TProps >, notify: () => void ) {\n\treturn ( { component, id, options = {} }: InjectArgs< TProps > ) => {\n\t\tif ( injections.has( id ) && ! options?.overwrite ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t`An injection with the id \"${ id }\" already exists. Did you mean to use \"options.overwrite\"?`\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n","import * as React from 'react';\nimport { useSyncExternalStore } from 'react';\n\nimport InjectedComponentWrapper from './components/injected-component-wrapper';\nimport { type AnyProps, type Id, type InjectedComponent, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport const DEFAULT_PRIORITY = 10;\n\n// Allow flushing all injections at once, for testing purposes.\nexport const flushInjectionsFns: ( () => void )[] = [];\n\nexport function flushAllInjections() {\n\tflushInjectionsFns.forEach( ( flush ) => flush() );\n}\n\nexport function registerFlushInjections( flush: () => void ) {\n\tflushInjectionsFns.push( flush );\n}\n\nexport type Subscribe = ( listener: () => void ) => () => void;\n\nexport function createSubscription() {\n\tconst listeners = new Set< () => void >();\n\n\treturn {\n\t\tsubscribe: ( listener: () => void ) => {\n\t\t\tlisteners.add( listener );\n\n\t\t\treturn () => listeners.delete( listener );\n\t\t},\n\t\tnotify: () => listeners.forEach( ( listener ) => listener() ),\n\t};\n}\n\nexport function createGetInjections< TProps extends object = AnyProps >( injections: InjectionsMap< TProps > ) {\n\treturn () => [ ...injections.values() ].sort( ( a, b ) => a.priority - b.priority );\n}\n\n// Injections registered after the `Slot` has already mounted (e.g. by an external plugin's\n// script that loads after the editor has rendered) must still be reflected in the UI, so the\n// snapshot is invalidated and re-read whenever `notify()` is called.\nexport function createUseInjections< TProps extends object = AnyProps >(\n\tgetInjections: Location< TProps >[ 'getInjections' ],\n\tsubscribe: Subscribe\n) {\n\tlet snapshot: ReturnType< Location< TProps >[ 'getInjections' ] > | null = null;\n\n\tsubscribe( () => {\n\t\tsnapshot = null;\n\t} );\n\n\tconst getSnapshot = () => {\n\t\tif ( ! snapshot ) {\n\t\t\tsnapshot = getInjections();\n\t\t}\n\n\t\treturn snapshot;\n\t};\n\n\treturn () => useSyncExternalStore( subscribe, getSnapshot );\n}\n\nexport function wrapInjectedComponent< TProps extends object = AnyProps >( Component: InjectedComponent< TProps > ) {\n\treturn ( props: TProps ) => (\n\t\t<InjectedComponentWrapper>\n\t\t\t<Component { ...props } />\n\t\t</InjectedComponentWrapper>\n\t);\n}\n","import * as React from 'react';\nimport { type ReactNode, Suspense } from 'react';\n\nimport ErrorBoundary from './error-boundary';\n\nexport default function InjectedComponentWrapper( { children }: { children: ReactNode } ) {\n\treturn (\n\t\t<ErrorBoundary fallback={ null }>\n\t\t\t<Suspense fallback={ null }>{ children }</Suspense>\n\t\t</ErrorBoundary>\n\t);\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n\tchildren?: ReactNode;\n\tfallback: ReactNode;\n}\n\ninterface State {\n\thasError: boolean;\n}\n\nexport default class ErrorBoundary extends Component< Props, State > {\n\tpublic state: State = {\n\t\thasError: false,\n\t};\n\n\tpublic static getDerivedStateFromError(): State {\n\t\t// Update state so the next render will show the fallback UI.\n\t\treturn { hasError: true };\n\t}\n\n\tpublic render() {\n\t\tif ( this.state.hasError ) {\n\t\t\treturn this.props.fallback;\n\t\t}\n\n\t\treturn this.props.children;\n\t}\n}\n","import * as React from 'react';\nimport { type PropsWithChildren } from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport {\n\ttype AnyProps,\n\ttype Id,\n\ttype ReplaceableInjectArgs,\n\ttype ReplaceableInjection,\n\ttype ReplaceableLocation,\n} from './types';\n\ntype ReplaceableInjectionsMap< TProps extends object = AnyProps > = Map< Id, ReplaceableInjection< TProps > >;\n\nexport function createReplaceableLocation< TProps extends object = AnyProps >(): ReplaceableLocation< TProps > {\n\tconst injections: ReplaceableInjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createReplaceable( useInjections );\n\tconst inject = createRegister( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tinject,\n\t\tSlot,\n\t};\n}\n\nfunction createReplaceable< TProps extends PropsWithChildren< object > = AnyProps >(\n\tuseInjections: ReplaceableLocation< TProps >[ 'useInjections' ]\n) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\tconst { component: Component } = injections.find( ( { condition } ) => condition?.( props ) ) ?? {};\n\n\t\tif ( ! Component ) {\n\t\t\treturn props.children;\n\t\t}\n\n\t\treturn <Component { ...props } />;\n\t};\n}\n\nfunction createRegister< TProps extends object = AnyProps >(\n\tinjections: ReplaceableInjectionsMap< TProps >,\n\tnotify: () => void\n) {\n\treturn ( { component, id, condition = () => true, options = {} }: ReplaceableInjectArgs< TProps > ) => {\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tcondition,\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n"],"mappings":"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","names":["React","React","import_react","import_react","Component","Component","React","Component"]}
|
package/dist/index.mjs
CHANGED
|
@@ -37,6 +37,9 @@ var flushInjectionsFns = [];
|
|
|
37
37
|
function flushAllInjections() {
|
|
38
38
|
flushInjectionsFns.forEach((flush) => flush());
|
|
39
39
|
}
|
|
40
|
+
function registerFlushInjections(flush) {
|
|
41
|
+
flushInjectionsFns.push(flush);
|
|
42
|
+
}
|
|
40
43
|
function createSubscription() {
|
|
41
44
|
const listeners = /* @__PURE__ */ new Set();
|
|
42
45
|
return {
|
|
@@ -152,6 +155,7 @@ function createRegister(injections, notify) {
|
|
|
152
155
|
}
|
|
153
156
|
export {
|
|
154
157
|
flushAllInjections as __flushAllInjections,
|
|
158
|
+
registerFlushInjections as __registerFlushInjections,
|
|
155
159
|
createLocation,
|
|
156
160
|
createReplaceableLocation
|
|
157
161
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/create-location.tsx","../src/injections.tsx","../src/components/injected-component-wrapper.tsx","../src/components/error-boundary.tsx","../src/create-replaceable-location.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport { type AnyProps, type Id, type InjectArgs, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport function createLocation< TProps extends object = AnyProps >(): Location< TProps > {\n\tconst injections: InjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createSlot( useInjections );\n\tconst inject = createInject( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tinject,\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tSlot,\n\t};\n}\n\nfunction createSlot< TProps extends object = AnyProps >( useInjections: Location< TProps >[ 'useInjections' ] ) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ injections.map( ( { id, component: Component } ) => (\n\t\t\t\t\t<Component { ...props } key={ id } />\n\t\t\t\t) ) }\n\t\t\t</>\n\t\t);\n\t};\n}\n\nfunction createInject< TProps extends object = AnyProps >( injections: InjectionsMap< TProps >, notify: () => void ) {\n\treturn ( { component, id, options = {} }: InjectArgs< TProps > ) => {\n\t\tif ( injections.has( id ) && ! options?.overwrite ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t`An injection with the id \"${ id }\" already exists. Did you mean to use \"options.overwrite\"?`\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n","import * as React from 'react';\nimport { useSyncExternalStore } from 'react';\n\nimport InjectedComponentWrapper from './components/injected-component-wrapper';\nimport { type AnyProps, type Id, type InjectedComponent, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport const DEFAULT_PRIORITY = 10;\n\n// Allow flushing all injections at once, for testing purposes.\nexport const flushInjectionsFns: ( () => void )[] = [];\n\nexport function flushAllInjections() {\n\tflushInjectionsFns.forEach( ( flush ) => flush() );\n}\n\nexport type Subscribe = ( listener: () => void ) => () => void;\n\nexport function createSubscription() {\n\tconst listeners = new Set< () => void >();\n\n\treturn {\n\t\tsubscribe: ( listener: () => void ) => {\n\t\t\tlisteners.add( listener );\n\n\t\t\treturn () => listeners.delete( listener );\n\t\t},\n\t\tnotify: () => listeners.forEach( ( listener ) => listener() ),\n\t};\n}\n\nexport function createGetInjections< TProps extends object = AnyProps >( injections: InjectionsMap< TProps > ) {\n\treturn () => [ ...injections.values() ].sort( ( a, b ) => a.priority - b.priority );\n}\n\n// Injections registered after the `Slot` has already mounted (e.g. by an external plugin's\n// script that loads after the editor has rendered) must still be reflected in the UI, so the\n// snapshot is invalidated and re-read whenever `notify()` is called.\nexport function createUseInjections< TProps extends object = AnyProps >(\n\tgetInjections: Location< TProps >[ 'getInjections' ],\n\tsubscribe: Subscribe\n) {\n\tlet snapshot: ReturnType< Location< TProps >[ 'getInjections' ] > | null = null;\n\n\tsubscribe( () => {\n\t\tsnapshot = null;\n\t} );\n\n\tconst getSnapshot = () => {\n\t\tif ( ! snapshot ) {\n\t\t\tsnapshot = getInjections();\n\t\t}\n\n\t\treturn snapshot;\n\t};\n\n\treturn () => useSyncExternalStore( subscribe, getSnapshot );\n}\n\nexport function wrapInjectedComponent< TProps extends object = AnyProps >( Component: InjectedComponent< TProps > ) {\n\treturn ( props: TProps ) => (\n\t\t<InjectedComponentWrapper>\n\t\t\t<Component { ...props } />\n\t\t</InjectedComponentWrapper>\n\t);\n}\n","import * as React from 'react';\nimport { type ReactNode, Suspense } from 'react';\n\nimport ErrorBoundary from './error-boundary';\n\nexport default function InjectedComponentWrapper( { children }: { children: ReactNode } ) {\n\treturn (\n\t\t<ErrorBoundary fallback={ null }>\n\t\t\t<Suspense fallback={ null }>{ children }</Suspense>\n\t\t</ErrorBoundary>\n\t);\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n\tchildren?: ReactNode;\n\tfallback: ReactNode;\n}\n\ninterface State {\n\thasError: boolean;\n}\n\nexport default class ErrorBoundary extends Component< Props, State > {\n\tpublic state: State = {\n\t\thasError: false,\n\t};\n\n\tpublic static getDerivedStateFromError(): State {\n\t\t// Update state so the next render will show the fallback UI.\n\t\treturn { hasError: true };\n\t}\n\n\tpublic render() {\n\t\tif ( this.state.hasError ) {\n\t\t\treturn this.props.fallback;\n\t\t}\n\n\t\treturn this.props.children;\n\t}\n}\n","import * as React from 'react';\nimport { type PropsWithChildren } from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport {\n\ttype AnyProps,\n\ttype Id,\n\ttype ReplaceableInjectArgs,\n\ttype ReplaceableInjection,\n\ttype ReplaceableLocation,\n} from './types';\n\ntype ReplaceableInjectionsMap< TProps extends object = AnyProps > = Map< Id, ReplaceableInjection< TProps > >;\n\nexport function createReplaceableLocation< TProps extends object = AnyProps >(): ReplaceableLocation< TProps > {\n\tconst injections: ReplaceableInjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createReplaceable( useInjections );\n\tconst inject = createRegister( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tinject,\n\t\tSlot,\n\t};\n}\n\nfunction createReplaceable< TProps extends PropsWithChildren< object > = AnyProps >(\n\tuseInjections: ReplaceableLocation< TProps >[ 'useInjections' ]\n) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\tconst { component: Component } = injections.find( ( { condition } ) => condition?.( props ) ) ?? {};\n\n\t\tif ( ! Component ) {\n\t\t\treturn props.children;\n\t\t}\n\n\t\treturn <Component { ...props } />;\n\t};\n}\n\nfunction createRegister< TProps extends object = AnyProps >(\n\tinjections: ReplaceableInjectionsMap< TProps >,\n\tnotify: () => void\n) {\n\treturn ( { component, id, condition = () => true, options = {} }: ReplaceableInjectArgs< TProps > ) => {\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tcondition,\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n"],"mappings":"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","names":["React","React","Component","Component","React","Component"]}
|
|
1
|
+
{"version":3,"sources":["../src/create-location.tsx","../src/injections.tsx","../src/components/injected-component-wrapper.tsx","../src/components/error-boundary.tsx","../src/create-replaceable-location.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport { type AnyProps, type Id, type InjectArgs, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport function createLocation< TProps extends object = AnyProps >(): Location< TProps > {\n\tconst injections: InjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createSlot( useInjections );\n\tconst inject = createInject( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tinject,\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tSlot,\n\t};\n}\n\nfunction createSlot< TProps extends object = AnyProps >( useInjections: Location< TProps >[ 'useInjections' ] ) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ injections.map( ( { id, component: Component } ) => (\n\t\t\t\t\t<Component { ...props } key={ id } />\n\t\t\t\t) ) }\n\t\t\t</>\n\t\t);\n\t};\n}\n\nfunction createInject< TProps extends object = AnyProps >( injections: InjectionsMap< TProps >, notify: () => void ) {\n\treturn ( { component, id, options = {} }: InjectArgs< TProps > ) => {\n\t\tif ( injections.has( id ) && ! options?.overwrite ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t`An injection with the id \"${ id }\" already exists. Did you mean to use \"options.overwrite\"?`\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n","import * as React from 'react';\nimport { useSyncExternalStore } from 'react';\n\nimport InjectedComponentWrapper from './components/injected-component-wrapper';\nimport { type AnyProps, type Id, type InjectedComponent, type Injection, type Location } from './types';\n\ntype InjectionsMap< TProps extends object = AnyProps > = Map< Id, Injection< TProps > >;\n\nexport const DEFAULT_PRIORITY = 10;\n\n// Allow flushing all injections at once, for testing purposes.\nexport const flushInjectionsFns: ( () => void )[] = [];\n\nexport function flushAllInjections() {\n\tflushInjectionsFns.forEach( ( flush ) => flush() );\n}\n\nexport function registerFlushInjections( flush: () => void ) {\n\tflushInjectionsFns.push( flush );\n}\n\nexport type Subscribe = ( listener: () => void ) => () => void;\n\nexport function createSubscription() {\n\tconst listeners = new Set< () => void >();\n\n\treturn {\n\t\tsubscribe: ( listener: () => void ) => {\n\t\t\tlisteners.add( listener );\n\n\t\t\treturn () => listeners.delete( listener );\n\t\t},\n\t\tnotify: () => listeners.forEach( ( listener ) => listener() ),\n\t};\n}\n\nexport function createGetInjections< TProps extends object = AnyProps >( injections: InjectionsMap< TProps > ) {\n\treturn () => [ ...injections.values() ].sort( ( a, b ) => a.priority - b.priority );\n}\n\n// Injections registered after the `Slot` has already mounted (e.g. by an external plugin's\n// script that loads after the editor has rendered) must still be reflected in the UI, so the\n// snapshot is invalidated and re-read whenever `notify()` is called.\nexport function createUseInjections< TProps extends object = AnyProps >(\n\tgetInjections: Location< TProps >[ 'getInjections' ],\n\tsubscribe: Subscribe\n) {\n\tlet snapshot: ReturnType< Location< TProps >[ 'getInjections' ] > | null = null;\n\n\tsubscribe( () => {\n\t\tsnapshot = null;\n\t} );\n\n\tconst getSnapshot = () => {\n\t\tif ( ! snapshot ) {\n\t\t\tsnapshot = getInjections();\n\t\t}\n\n\t\treturn snapshot;\n\t};\n\n\treturn () => useSyncExternalStore( subscribe, getSnapshot );\n}\n\nexport function wrapInjectedComponent< TProps extends object = AnyProps >( Component: InjectedComponent< TProps > ) {\n\treturn ( props: TProps ) => (\n\t\t<InjectedComponentWrapper>\n\t\t\t<Component { ...props } />\n\t\t</InjectedComponentWrapper>\n\t);\n}\n","import * as React from 'react';\nimport { type ReactNode, Suspense } from 'react';\n\nimport ErrorBoundary from './error-boundary';\n\nexport default function InjectedComponentWrapper( { children }: { children: ReactNode } ) {\n\treturn (\n\t\t<ErrorBoundary fallback={ null }>\n\t\t\t<Suspense fallback={ null }>{ children }</Suspense>\n\t\t</ErrorBoundary>\n\t);\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n\tchildren?: ReactNode;\n\tfallback: ReactNode;\n}\n\ninterface State {\n\thasError: boolean;\n}\n\nexport default class ErrorBoundary extends Component< Props, State > {\n\tpublic state: State = {\n\t\thasError: false,\n\t};\n\n\tpublic static getDerivedStateFromError(): State {\n\t\t// Update state so the next render will show the fallback UI.\n\t\treturn { hasError: true };\n\t}\n\n\tpublic render() {\n\t\tif ( this.state.hasError ) {\n\t\t\treturn this.props.fallback;\n\t\t}\n\n\t\treturn this.props.children;\n\t}\n}\n","import * as React from 'react';\nimport { type PropsWithChildren } from 'react';\n\nimport {\n\tcreateGetInjections,\n\tcreateSubscription,\n\tcreateUseInjections,\n\tDEFAULT_PRIORITY,\n\tflushInjectionsFns,\n\twrapInjectedComponent,\n} from './injections';\nimport {\n\ttype AnyProps,\n\ttype Id,\n\ttype ReplaceableInjectArgs,\n\ttype ReplaceableInjection,\n\ttype ReplaceableLocation,\n} from './types';\n\ntype ReplaceableInjectionsMap< TProps extends object = AnyProps > = Map< Id, ReplaceableInjection< TProps > >;\n\nexport function createReplaceableLocation< TProps extends object = AnyProps >(): ReplaceableLocation< TProps > {\n\tconst injections: ReplaceableInjectionsMap< TProps > = new Map();\n\tconst { subscribe, notify } = createSubscription();\n\n\tconst getInjections = createGetInjections( injections );\n\tconst useInjections = createUseInjections( getInjections, subscribe );\n\tconst Slot = createReplaceable( useInjections );\n\tconst inject = createRegister( injections, notify );\n\n\t// Push the clear function to the flushInjectionsFns array, so we can flush all injections at once.\n\t// `notify()` is called too, so any mounted `Slot` (and its cached snapshot) reflects the flush,\n\t// which matters for test isolation between test cases.\n\tflushInjectionsFns.push( () => {\n\t\tinjections.clear();\n\t\tnotify();\n\t} );\n\n\treturn {\n\t\tgetInjections,\n\t\tuseInjections,\n\t\tinject,\n\t\tSlot,\n\t};\n}\n\nfunction createReplaceable< TProps extends PropsWithChildren< object > = AnyProps >(\n\tuseInjections: ReplaceableLocation< TProps >[ 'useInjections' ]\n) {\n\treturn ( props: TProps ) => {\n\t\tconst injections = useInjections();\n\n\t\tconst { component: Component } = injections.find( ( { condition } ) => condition?.( props ) ) ?? {};\n\n\t\tif ( ! Component ) {\n\t\t\treturn props.children;\n\t\t}\n\n\t\treturn <Component { ...props } />;\n\t};\n}\n\nfunction createRegister< TProps extends object = AnyProps >(\n\tinjections: ReplaceableInjectionsMap< TProps >,\n\tnotify: () => void\n) {\n\treturn ( { component, id, condition = () => true, options = {} }: ReplaceableInjectArgs< TProps > ) => {\n\t\tinjections.set( id, {\n\t\t\tid,\n\t\t\tcomponent: wrapInjectedComponent( component ),\n\t\t\tcondition,\n\t\t\tpriority: options.priority ?? DEFAULT_PRIORITY,\n\t\t} );\n\n\t\tnotify();\n\t};\n}\n"],"mappings":"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","names":["React","React","Component","Component","React","Component"]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,4 +2,7 @@ export * from './types';
|
|
|
2
2
|
|
|
3
3
|
export { createLocation } from './create-location';
|
|
4
4
|
export { createReplaceableLocation } from './create-replaceable-location';
|
|
5
|
-
export {
|
|
5
|
+
export {
|
|
6
|
+
flushAllInjections as __flushAllInjections,
|
|
7
|
+
registerFlushInjections as __registerFlushInjections,
|
|
8
|
+
} from './injections';
|
package/src/injections.tsx
CHANGED
|
@@ -15,6 +15,10 @@ export function flushAllInjections() {
|
|
|
15
15
|
flushInjectionsFns.forEach( ( flush ) => flush() );
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
export function registerFlushInjections( flush: () => void ) {
|
|
19
|
+
flushInjectionsFns.push( flush );
|
|
20
|
+
}
|
|
21
|
+
|
|
18
22
|
export type Subscribe = ( listener: () => void ) => () => void;
|
|
19
23
|
|
|
20
24
|
export function createSubscription() {
|