shelving 1.110.4 → 1.111.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.
- package/db/ItemStore.d.ts +2 -2
- package/db/ItemStore.js +1 -1
- package/db/QueryStore.d.ts +2 -2
- package/db/QueryStore.js +1 -1
- package/package.json +1 -1
- package/react/index.d.ts +1 -0
- package/react/index.js +1 -0
- package/react/useMount.d.ts +8 -0
- package/react/useMount.js +23 -0
- package/sequence/LazyDeferredSequence.d.ts +3 -6
- package/sequence/LazyDeferredSequence.js +8 -17
- package/store/LazyStore.d.ts +4 -9
- package/store/LazyStore.js +7 -20
- package/util/async.d.ts +4 -3
- package/util/callback.d.ts +0 -6
- package/util/error.d.ts +4 -3
- package/util/error.js +1 -0
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/util/sequence.d.ts +4 -2
- package/util/start.d.ts +18 -0
- package/util/start.js +26 -0
- package/util/template.d.ts +2 -2
- package/util/template.js +15 -9
package/db/ItemStore.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AbstractProvider } from "./Provider.js";
|
|
2
|
-
import type { StopCallback } from "../util/callback.js";
|
|
3
2
|
import type { DataKey, Database } from "../util/data.js";
|
|
4
3
|
import type { Item, OptionalItem } from "../util/item.js";
|
|
4
|
+
import type { Stop } from "../util/start.js";
|
|
5
5
|
import { BooleanStore } from "../store/BooleanStore.js";
|
|
6
6
|
import { LazyStore } from "../store/LazyStore.js";
|
|
7
7
|
/** Store a single item. */
|
|
@@ -23,5 +23,5 @@ export declare class ItemStore<T extends Database, K extends DataKey<T>> extends
|
|
|
23
23
|
/** Refresh this store if data in the cache is older than `maxAge` (in milliseconds). */
|
|
24
24
|
refreshStale(maxAge: number, provider?: AbstractProvider<T>): void;
|
|
25
25
|
/** Subscribe this store to a provider. */
|
|
26
|
-
connect(provider?: AbstractProvider<T>):
|
|
26
|
+
connect(provider?: AbstractProvider<T>): Stop;
|
|
27
27
|
}
|
package/db/ItemStore.js
CHANGED
|
@@ -34,7 +34,7 @@ export class ItemStore extends LazyStore {
|
|
|
34
34
|
this.collection = collection;
|
|
35
35
|
this.id = id;
|
|
36
36
|
// Start loading the value from the provider if it doesn't exist.
|
|
37
|
-
if (time ===
|
|
37
|
+
if (time === undefined)
|
|
38
38
|
this.refresh();
|
|
39
39
|
}
|
|
40
40
|
/** Refresh this store from the source provider. */
|
package/db/QueryStore.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AbstractProvider } from "./Provider.js";
|
|
2
|
-
import type { StopCallback } from "../util/callback.js";
|
|
3
2
|
import type { DataKey, Database } from "../util/data.js";
|
|
4
3
|
import type { Item, ItemQuery, Items, OptionalItem } from "../util/item.js";
|
|
4
|
+
import type { Stop } from "../util/start.js";
|
|
5
5
|
import { BooleanStore } from "../store/BooleanStore.js";
|
|
6
6
|
import { LazyStore } from "../store/LazyStore.js";
|
|
7
7
|
/** Store a set of multiple items. */
|
|
@@ -33,7 +33,7 @@ export declare class QueryStore<T extends Database, K extends DataKey<T>> extend
|
|
|
33
33
|
/** Refresh this store if data in the cache is older than `maxAge` (in milliseconds). */
|
|
34
34
|
refreshStale(maxAge: number): void;
|
|
35
35
|
/** Subscribe this store to a provider. */
|
|
36
|
-
connect(provider?: AbstractProvider<T>):
|
|
36
|
+
connect(provider?: AbstractProvider<T>): Stop;
|
|
37
37
|
/**
|
|
38
38
|
* Load more items after the last once.
|
|
39
39
|
* - Promise that needs to be handled.
|
package/db/QueryStore.js
CHANGED
|
@@ -53,7 +53,7 @@ export class QueryStore extends LazyStore {
|
|
|
53
53
|
this.query = query;
|
|
54
54
|
this.limit = getLimit(query) ?? Infinity;
|
|
55
55
|
// Start loading the value from the provider if it doesn't exist.
|
|
56
|
-
if (time ===
|
|
56
|
+
if (time === undefined)
|
|
57
57
|
this.refresh();
|
|
58
58
|
}
|
|
59
59
|
/** Refresh this store from the source provider. */
|
package/package.json
CHANGED
package/react/index.d.ts
CHANGED
package/react/index.js
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { type Start } from "../util/start.js";
|
|
3
|
+
/**
|
|
4
|
+
* Call a `StartCallback` when an element is mounted, and the returned `StopCallback` when it's unmounted again.
|
|
5
|
+
* - Takes care of state so `start()` won't be called twice for the same element.
|
|
6
|
+
* - Returns a `RefCallback` which should be set as `ref={ref}` on the target element.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMount<T extends Element>(start: Start<[T]>): React.RefCallback<T>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { Starter } from "../util/start.js";
|
|
3
|
+
/**
|
|
4
|
+
* Call a `StartCallback` when an element is mounted, and the returned `StopCallback` when it's unmounted again.
|
|
5
|
+
* - Takes care of state so `start()` won't be called twice for the same element.
|
|
6
|
+
* - Returns a `RefCallback` which should be set as `ref={ref}` on the target element.
|
|
7
|
+
*/
|
|
8
|
+
export function useMount(start) {
|
|
9
|
+
const ref = useRef();
|
|
10
|
+
if (!ref.current) {
|
|
11
|
+
let current;
|
|
12
|
+
const starter = new Starter(start);
|
|
13
|
+
ref.current = (next) => {
|
|
14
|
+
if (current !== next) {
|
|
15
|
+
starter.stop();
|
|
16
|
+
current = next;
|
|
17
|
+
if (current)
|
|
18
|
+
starter.start(current);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return ref.current;
|
|
23
|
+
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import type { StartCallback } from "../util/callback.js";
|
|
2
1
|
import type { Disposable } from "../util/dispose.js";
|
|
2
|
+
import { type Start } from "../util/start.js";
|
|
3
3
|
import { DeferredSequence } from "./DeferredSequence.js";
|
|
4
4
|
/** Deferred sequence of values that calls a `StartCallback` when it has iterators that are iterating, and calls the corresponding `StopCallback` when all iterators have finished. */
|
|
5
5
|
export declare class LazyDeferredSequence<T = void> extends DeferredSequence<T> implements Disposable {
|
|
6
6
|
private _iterating;
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
constructor(start: StartCallback<LazyDeferredSequence<T>>);
|
|
7
|
+
private _starter;
|
|
8
|
+
constructor(start: Start<[DeferredSequence<T>]>);
|
|
10
9
|
[Symbol.asyncIterator](): AsyncGenerator<T, void, void>;
|
|
11
|
-
start(): void;
|
|
12
|
-
stop(): void;
|
|
13
10
|
[Symbol.dispose](): void;
|
|
14
11
|
}
|
|
@@ -1,39 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Starter } from "../util/start.js";
|
|
2
2
|
import { DeferredSequence } from "./DeferredSequence.js";
|
|
3
3
|
import { IteratorSequence } from "./IteratorSequence.js";
|
|
4
4
|
/** Deferred sequence of values that calls a `StartCallback` when it has iterators that are iterating, and calls the corresponding `StopCallback` when all iterators have finished. */
|
|
5
5
|
export class LazyDeferredSequence extends DeferredSequence {
|
|
6
6
|
_iterating = 0;
|
|
7
|
-
|
|
8
|
-
_stop = undefined;
|
|
7
|
+
_starter;
|
|
9
8
|
constructor(start) {
|
|
10
9
|
super();
|
|
11
|
-
this.
|
|
10
|
+
this._starter = new Starter(start);
|
|
12
11
|
}
|
|
13
12
|
async *[Symbol.asyncIterator]() {
|
|
14
|
-
this.start();
|
|
13
|
+
this._starter.start(this);
|
|
15
14
|
this._iterating++;
|
|
16
15
|
try {
|
|
17
16
|
// Delegate to the superclass's async iterator.
|
|
18
|
-
// Wrap in an `IteratorSequence` because we know the superclass returns `this`
|
|
17
|
+
// Wrap in an `IteratorSequence` because we know the superclass `AbstractSequence.prototype.[Symbol.asyncIterator]()` simply returns `this`
|
|
19
18
|
// `yield* this` would call this method again and cause an infinite loop.
|
|
20
19
|
yield* new IteratorSequence(super[Symbol.asyncIterator]());
|
|
21
20
|
}
|
|
22
21
|
finally {
|
|
23
22
|
this._iterating--;
|
|
24
|
-
if (this._iterating < 1
|
|
25
|
-
this.stop();
|
|
23
|
+
if (this._iterating < 1)
|
|
24
|
+
this._starter.stop();
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
|
-
start() {
|
|
29
|
-
if (!this._stop)
|
|
30
|
-
this._stop = this._start(this);
|
|
31
|
-
}
|
|
32
|
-
stop() {
|
|
33
|
-
if (this._stop)
|
|
34
|
-
this._stop = void call(this._stop);
|
|
35
|
-
}
|
|
36
27
|
[Symbol.dispose]() {
|
|
37
|
-
this.
|
|
28
|
+
this._starter[Symbol.dispose]();
|
|
38
29
|
}
|
|
39
30
|
}
|
package/store/LazyStore.d.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import type { NONE } from "../util/constants.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type Start } from "../util/start.js";
|
|
4
4
|
import { Store } from "./Store.js";
|
|
5
5
|
/** Store that starts/stops a source subscription when things subscribe to it, and stops when everything has unsubscribed from it. */
|
|
6
6
|
export declare class LazyStore<T> extends Store<T> implements Disposable {
|
|
7
|
-
constructor(start: StartCallback<Store<T>>, value: T | typeof NONE, time?: number);
|
|
8
|
-
[Symbol.asyncIterator](): AsyncGenerator<T, void, void>;
|
|
9
7
|
private _iterating;
|
|
10
|
-
|
|
11
|
-
start
|
|
12
|
-
|
|
13
|
-
/** Stop subscription to `MemoryProvider` if there is one. */
|
|
14
|
-
stop(): void;
|
|
15
|
-
private _stop;
|
|
8
|
+
private readonly _starter;
|
|
9
|
+
constructor(start: Start<[Store<T>]>, value: T | typeof NONE, time?: number);
|
|
10
|
+
[Symbol.asyncIterator](): AsyncGenerator<T, void, void>;
|
|
16
11
|
[Symbol.dispose](): void;
|
|
17
12
|
}
|
package/store/LazyStore.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Starter } from "../util/start.js";
|
|
2
2
|
import { Store } from "./Store.js";
|
|
3
3
|
/** Store that starts/stops a source subscription when things subscribe to it, and stops when everything has unsubscribed from it. */
|
|
4
4
|
export class LazyStore extends Store {
|
|
5
|
+
_iterating = 0;
|
|
6
|
+
_starter;
|
|
5
7
|
constructor(start, value, time) {
|
|
6
8
|
super(value, time);
|
|
7
|
-
this.
|
|
9
|
+
this._starter = new Starter(start);
|
|
8
10
|
}
|
|
9
|
-
// Override to subscribe to start/stop the source subscription when things subscribe to this.
|
|
10
11
|
async *[Symbol.asyncIterator]() {
|
|
11
|
-
this.start();
|
|
12
|
+
this._starter.start(this);
|
|
12
13
|
this._iterating++;
|
|
13
14
|
try {
|
|
14
15
|
yield* super[Symbol.asyncIterator]();
|
|
@@ -16,24 +17,10 @@ export class LazyStore extends Store {
|
|
|
16
17
|
finally {
|
|
17
18
|
this._iterating--;
|
|
18
19
|
if (this._iterating < 1)
|
|
19
|
-
this.stop();
|
|
20
|
+
this._starter.stop();
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
|
-
_iterating = 0;
|
|
23
|
-
/** Start subscription to `MemoryProvider` if there is one. */
|
|
24
|
-
start() {
|
|
25
|
-
if (!this._stop)
|
|
26
|
-
this._stop = this._start(this);
|
|
27
|
-
}
|
|
28
|
-
_start;
|
|
29
|
-
/** Stop subscription to `MemoryProvider` if there is one. */
|
|
30
|
-
stop() {
|
|
31
|
-
if (this._stop)
|
|
32
|
-
this._stop = void call(this._stop);
|
|
33
|
-
}
|
|
34
|
-
_stop = undefined;
|
|
35
|
-
// Implement `Disposable`
|
|
36
23
|
[Symbol.dispose]() {
|
|
37
|
-
this.
|
|
24
|
+
this._starter[Symbol.dispose]();
|
|
38
25
|
}
|
|
39
26
|
}
|
package/util/async.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ValueCallback } from "./callback.js";
|
|
2
|
+
import type { Report } from "./error.js";
|
|
2
3
|
/** Is a value an asynchronous value implementing a `then()` function. */
|
|
3
4
|
export declare const isAsync: <T>(value: T | PromiseLike<T>) => value is PromiseLike<T>;
|
|
4
5
|
/** Is a value a synchronous value. */
|
|
@@ -23,14 +24,14 @@ export declare abstract class AbstractPromise<T> extends Promise<T> {
|
|
|
23
24
|
/** Resolve this promise with a value. */
|
|
24
25
|
protected readonly _resolve: ValueCallback<T>;
|
|
25
26
|
/** Reject this promise with a reason. */
|
|
26
|
-
protected readonly _reject:
|
|
27
|
+
protected readonly _reject: Report;
|
|
27
28
|
constructor();
|
|
28
29
|
}
|
|
29
30
|
/** Deferred allows you to access the internal resolve/reject callbacks of a `Promise` */
|
|
30
31
|
export type Deferred<T> = {
|
|
31
32
|
promise: Promise<T>;
|
|
32
33
|
resolve: ValueCallback<T>;
|
|
33
|
-
reject:
|
|
34
|
+
reject: Report;
|
|
34
35
|
};
|
|
35
36
|
/**
|
|
36
37
|
* Get a deferred to access the `resolve()` and `reject()` functions of a promise.
|
package/util/callback.d.ts
CHANGED
|
@@ -11,12 +11,6 @@ export type AsyncValueCallback<T = void> = (value: T) => void | PromiseLike<void
|
|
|
11
11
|
export type ValuesCallback<T extends Arguments = []> = (...values: T) => void;
|
|
12
12
|
/** Callback function that receives multiple values and possibly returns a promise that must be handled. */
|
|
13
13
|
export type AsyncValuesCallback<T extends Arguments = []> = (...values: T) => void | PromiseLike<void>;
|
|
14
|
-
/** Callback function that handles an error. */
|
|
15
|
-
export type ErrorCallback = (reason: unknown) => void;
|
|
16
|
-
/** Callback function that starts something (and returns an optional stop callback). */
|
|
17
|
-
export type StartCallback<T> = (value: T) => StopCallback;
|
|
18
|
-
/** Callback function that stops something. */
|
|
19
|
-
export type StopCallback = () => void;
|
|
20
14
|
/** Safely call a callback function (possibly with a value). */
|
|
21
15
|
export declare function call<A extends Arguments = []>(callback: (...v: A) => unknown, ...values: A): void;
|
|
22
16
|
/** Return a callback function that safely calls a callback function (possibly with a value). */
|
package/util/error.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/** Callback function that reports an error. */
|
|
2
|
+
export type Report = (reason: unknown) => void;
|
|
3
|
+
/** Log an error to the console. */
|
|
4
|
+
export declare const logError: Report;
|
package/util/error.js
CHANGED
package/util/index.d.ts
CHANGED
package/util/index.js
CHANGED
package/util/sequence.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { AsyncValueCallback,
|
|
1
|
+
import type { AsyncValueCallback, ValueCallback } from "./callback.js";
|
|
2
|
+
import type { Report } from "./error.js";
|
|
3
|
+
import type { Stop } from "./start.js";
|
|
2
4
|
import { STOP } from "./constants.js";
|
|
3
5
|
/**
|
|
4
6
|
* Is a value an async iterable object?
|
|
@@ -15,4 +17,4 @@ export declare function callSequence<T>(sequence: AsyncIterable<T>, callback: As
|
|
|
15
17
|
/** Get the first value from an async iterator. **/
|
|
16
18
|
export declare function getNextValue<T>(sequence: AsyncIterable<T>): Promise<T>;
|
|
17
19
|
/** Pull values from a sequence until the returned function is called. */
|
|
18
|
-
export declare function runSequence<T>(sequence: AsyncIterable<T>, onNext?: ValueCallback<T>, onError?:
|
|
20
|
+
export declare function runSequence<T>(sequence: AsyncIterable<T>, onNext?: ValueCallback<T>, onError?: Report): Stop;
|
package/util/start.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Disposable } from "./dispose.js";
|
|
2
|
+
import type { Arguments } from "./function.js";
|
|
3
|
+
/** Callback function that starts something with multiple values and returns an optional stop callback. */
|
|
4
|
+
export type Start<T extends Arguments = []> = (...values: T) => Stop | undefined;
|
|
5
|
+
/** Callback function that stops something. */
|
|
6
|
+
export type Stop = () => void;
|
|
7
|
+
/**
|
|
8
|
+
* Wrapper class to handle state on start/stop callback process.
|
|
9
|
+
* - If process has already started, `starter.start()` won't be called twice (including if `start()` didn't return a `stop()` callback).
|
|
10
|
+
*/
|
|
11
|
+
export declare class Starter<T extends Arguments = []> implements Disposable {
|
|
12
|
+
private readonly _start;
|
|
13
|
+
private _stop;
|
|
14
|
+
constructor(start: Start<T>);
|
|
15
|
+
start(...values: T): void;
|
|
16
|
+
stop(): void;
|
|
17
|
+
[Symbol.dispose](): void;
|
|
18
|
+
}
|
package/util/start.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { call } from "./callback.js";
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper class to handle state on start/stop callback process.
|
|
4
|
+
* - If process has already started, `starter.start()` won't be called twice (including if `start()` didn't return a `stop()` callback).
|
|
5
|
+
*/
|
|
6
|
+
export class Starter {
|
|
7
|
+
_start;
|
|
8
|
+
_stop = false;
|
|
9
|
+
constructor(start) {
|
|
10
|
+
this._start = start;
|
|
11
|
+
}
|
|
12
|
+
start(...values) {
|
|
13
|
+
if (this._stop === false)
|
|
14
|
+
this._stop = this._start(...values) || true;
|
|
15
|
+
}
|
|
16
|
+
stop() {
|
|
17
|
+
if (this._stop !== false) {
|
|
18
|
+
if (typeof this._stop === "function")
|
|
19
|
+
call(this._stop);
|
|
20
|
+
this._stop = false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
[Symbol.dispose]() {
|
|
24
|
+
this.stop();
|
|
25
|
+
}
|
|
26
|
+
}
|
package/util/template.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ type PlaceholderValues = string | ((name: string) => string) | string[] | Templa
|
|
|
10
10
|
* @param template The template including template placeholders, e.g. `:name-${country}/{city}`
|
|
11
11
|
* @returns Array of clean string names of found placeholders, e.g. `["name", "country", "city"]`
|
|
12
12
|
*/
|
|
13
|
-
export declare
|
|
13
|
+
export declare function getPlaceholders(template: string): readonly string[];
|
|
14
14
|
/**
|
|
15
15
|
* Match a template against a target string.
|
|
16
16
|
* - Turn ":year-:month" and "2016-06..." etc into `{ year: "2016"... }`
|
|
@@ -34,5 +34,5 @@ export declare function matchTemplates(templates: Iterable<string> & NotString,
|
|
|
34
34
|
*
|
|
35
35
|
* @throws {ReferenceError} If a placeholder in the template string is not specified in values.
|
|
36
36
|
*/
|
|
37
|
-
export declare
|
|
37
|
+
export declare function renderTemplate(template: string, value: PlaceholderValues): string;
|
|
38
38
|
export {};
|
package/util/template.js
CHANGED
|
@@ -15,8 +15,10 @@ const TEMPLATE_CACHE = new Map();
|
|
|
15
15
|
* @param template The template including template placeholders, e.g. `:name-${country}/{city}`
|
|
16
16
|
* @returns Array of strings alternating separator and placeholder.
|
|
17
17
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
function _splitTemplate(template) {
|
|
19
|
+
return TEMPLATE_CACHE.get(template) || setMapItem(TEMPLATE_CACHE, template, _split(template));
|
|
20
|
+
}
|
|
21
|
+
function _split(template) {
|
|
20
22
|
const matches = template.split(R_PLACEHOLDERS);
|
|
21
23
|
let asterisks = 0;
|
|
22
24
|
const chunks = [];
|
|
@@ -30,15 +32,19 @@ const _split = (template) => {
|
|
|
30
32
|
chunks.push({ pre, placeholder, name, post });
|
|
31
33
|
}
|
|
32
34
|
return chunks;
|
|
33
|
-
}
|
|
35
|
+
}
|
|
34
36
|
/**
|
|
35
37
|
* Get list of placeholders named in a template string.
|
|
36
38
|
*
|
|
37
39
|
* @param template The template including template placeholders, e.g. `:name-${country}/{city}`
|
|
38
40
|
* @returns Array of clean string names of found placeholders, e.g. `["name", "country", "city"]`
|
|
39
41
|
*/
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
+
export function getPlaceholders(template) {
|
|
43
|
+
return _splitTemplate(template).map(_getPlaceholder);
|
|
44
|
+
}
|
|
45
|
+
function _getPlaceholder({ name }) {
|
|
46
|
+
return name;
|
|
47
|
+
}
|
|
42
48
|
/**
|
|
43
49
|
* Match a template against a target string.
|
|
44
50
|
* - Turn ":year-:month" and "2016-06..." etc into `{ year: "2016"... }`
|
|
@@ -94,7 +100,7 @@ export function matchTemplates(templates, target) {
|
|
|
94
100
|
*
|
|
95
101
|
* @throws {ReferenceError} If a placeholder in the template string is not specified in values.
|
|
96
102
|
*/
|
|
97
|
-
export
|
|
103
|
+
export function renderTemplate(template, value) {
|
|
98
104
|
const chunks = _splitTemplate(template);
|
|
99
105
|
if (!chunks.length)
|
|
100
106
|
return template;
|
|
@@ -102,8 +108,8 @@ export const renderTemplate = (template, value) => {
|
|
|
102
108
|
for (const { name, placeholder } of chunks)
|
|
103
109
|
output = output.replace(placeholder, _replace(name, value));
|
|
104
110
|
return output;
|
|
105
|
-
}
|
|
106
|
-
|
|
111
|
+
}
|
|
112
|
+
function _replace(name, value) {
|
|
107
113
|
if (typeof value === "string")
|
|
108
114
|
return value;
|
|
109
115
|
if (typeof value === "function")
|
|
@@ -114,4 +120,4 @@ const _replace = (name, value) => {
|
|
|
114
120
|
return v;
|
|
115
121
|
}
|
|
116
122
|
throw new ReferenceError(`Template "value.${name}" must be defined`);
|
|
117
|
-
}
|
|
123
|
+
}
|