vira 28.8.0 → 28.9.0
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.
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type Values } from '@augment-vir/common';
|
|
2
|
+
import { type AsyncProp, type DeclarativeElementDefinition } from 'element-vir';
|
|
3
|
+
import { type RequireExactlyOne } from 'type-fest';
|
|
4
|
+
/**
|
|
5
|
+
* Base type for loaders passed to {@link createDynamicElementLoader}.
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
9
|
+
export type BaseDynamicElementLoaders = Record<string, () => Promise<DeclarativeElementDefinition>>;
|
|
10
|
+
/**
|
|
11
|
+
* Create a dynamic element loader. This should go in your element state. This makes deferring
|
|
12
|
+
* element importing convenient and allows parts of your app to be placed in separate bundles. Make
|
|
13
|
+
* sure to also use {@link renderDynamicElement} to use the output of this loader.
|
|
14
|
+
*
|
|
15
|
+
* @category Util
|
|
16
|
+
* @see {@link renderDynamicElement}
|
|
17
|
+
* @see [example usage](https://github.com/electrovir/vira/blob/dev/packages/vira-book/src/element-book/entries/dynamic-elements.book.ts)
|
|
18
|
+
*/
|
|
19
|
+
export declare function createDynamicElementLoader<const Loaders extends Readonly<BaseDynamicElementLoaders>>(loaders: Readonly<Loaders>): DynamicElementAsyncProp<Loaders>;
|
|
20
|
+
/**
|
|
21
|
+
* The value for the async prop {@link DynamicElementAsyncProp}.
|
|
22
|
+
*
|
|
23
|
+
* @category Internal
|
|
24
|
+
*/
|
|
25
|
+
export type DynamicElementValue<Loaders extends BaseDynamicElementLoaders> = {
|
|
26
|
+
cache: Partial<Record<keyof Loaders, DeclarativeElementDefinition>>;
|
|
27
|
+
element: Awaited<ReturnType<Values<Loaders>>>;
|
|
28
|
+
key: keyof Loaders;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* An async prop for dynamic loading elements. This is the output from
|
|
32
|
+
* {@link createDynamicElementLoader}.
|
|
33
|
+
*
|
|
34
|
+
* @category Internal
|
|
35
|
+
*/
|
|
36
|
+
export type DynamicElementAsyncProp<Loaders extends BaseDynamicElementLoaders> = AsyncProp<DynamicElementValue<Loaders>, keyof Loaders>;
|
|
37
|
+
/**
|
|
38
|
+
* Params for the `ready` callback in {@link renderDynamicElement}.
|
|
39
|
+
*
|
|
40
|
+
* @category Internal
|
|
41
|
+
*/
|
|
42
|
+
export type ReadyParams<Loaders extends Readonly<BaseDynamicElementLoaders>> = RequireExactlyOne<{
|
|
43
|
+
[Key in keyof Loaders]: Awaited<ReturnType<Loaders[Key]>>;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* Renders the current state of a dynamic element loader. This should go in your render function.
|
|
47
|
+
* Make sure to also use {@link createDynamicElementLoader} to create a dynamic loader in your
|
|
48
|
+
* element's state.
|
|
49
|
+
*
|
|
50
|
+
* @category Util
|
|
51
|
+
* @see {@link createDynamicElementLoader}
|
|
52
|
+
* @see [example usage](https://github.com/electrovir/vira/blob/dev/packages/vira-book/src/element-book/entries/dynamic-elements.book.ts)
|
|
53
|
+
*/
|
|
54
|
+
export declare function renderDynamicElement<const Loaders extends BaseDynamicElementLoaders, const LoadingReturnValue, const ReadyReturnValue, const ErrorReturnValue>(asyncProp: DynamicElementAsyncProp<Loaders>, { ready, loading, error, key, }: {
|
|
55
|
+
/**
|
|
56
|
+
* If this is left undefined (or falsy), the current key will not be set, whatever the
|
|
57
|
+
* existing key is will continue to be used.
|
|
58
|
+
*/
|
|
59
|
+
key?: keyof NoInfer<Loaders> | undefined;
|
|
60
|
+
loading(this: void, params: Promise<ReadyParams<NoInfer<Loaders>>>): LoadingReturnValue;
|
|
61
|
+
ready(this: void, params: ReadyParams<NoInfer<Loaders>>): ReadyReturnValue;
|
|
62
|
+
error(this: void, error: Error): ErrorReturnValue;
|
|
63
|
+
}): ReadyReturnValue | LoadingReturnValue | ErrorReturnValue;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { asyncProp } from 'element-vir';
|
|
2
|
+
/**
|
|
3
|
+
* Create a dynamic element loader. This should go in your element state. This makes deferring
|
|
4
|
+
* element importing convenient and allows parts of your app to be placed in separate bundles. Make
|
|
5
|
+
* sure to also use {@link renderDynamicElement} to use the output of this loader.
|
|
6
|
+
*
|
|
7
|
+
* @category Util
|
|
8
|
+
* @see {@link renderDynamicElement}
|
|
9
|
+
* @see [example usage](https://github.com/electrovir/vira/blob/dev/packages/vira-book/src/element-book/entries/dynamic-elements.book.ts)
|
|
10
|
+
*/
|
|
11
|
+
export function createDynamicElementLoader(loaders) {
|
|
12
|
+
return asyncProp({
|
|
13
|
+
async updateCallback(elementKey, previousResolvedValue) {
|
|
14
|
+
if (previousResolvedValue && elementKey in previousResolvedValue.cache) {
|
|
15
|
+
return {
|
|
16
|
+
cache: previousResolvedValue.cache,
|
|
17
|
+
element: previousResolvedValue.cache[elementKey],
|
|
18
|
+
key: elementKey,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const imported = await loaders[elementKey]();
|
|
22
|
+
return {
|
|
23
|
+
cache: {
|
|
24
|
+
...previousResolvedValue?.cache,
|
|
25
|
+
[elementKey]: imported,
|
|
26
|
+
},
|
|
27
|
+
element: imported,
|
|
28
|
+
key: elementKey,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Renders the current state of a dynamic element loader. This should go in your render function.
|
|
35
|
+
* Make sure to also use {@link createDynamicElementLoader} to create a dynamic loader in your
|
|
36
|
+
* element's state.
|
|
37
|
+
*
|
|
38
|
+
* @category Util
|
|
39
|
+
* @see {@link createDynamicElementLoader}
|
|
40
|
+
* @see [example usage](https://github.com/electrovir/vira/blob/dev/packages/vira-book/src/element-book/entries/dynamic-elements.book.ts)
|
|
41
|
+
*/
|
|
42
|
+
export function renderDynamicElement(asyncProp, { ready, loading, error, key, }) {
|
|
43
|
+
if (key) {
|
|
44
|
+
asyncProp.update(key);
|
|
45
|
+
}
|
|
46
|
+
if (asyncProp.value instanceof Error) {
|
|
47
|
+
return error(asyncProp.value);
|
|
48
|
+
}
|
|
49
|
+
else if (asyncProp.value instanceof Promise) {
|
|
50
|
+
return loading(asyncProp.value.then((value) => {
|
|
51
|
+
return {
|
|
52
|
+
[value.key]: value.element,
|
|
53
|
+
};
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return ready({
|
|
58
|
+
[asyncProp.value.key]: asyncProp.value.element,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
package/dist/util/index.d.ts
CHANGED
package/dist/util/index.js
CHANGED