Ship built output for consumers
This commit is contained in:
parent
0c430c3c0e
commit
9562d6a603
16 changed files with 302 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1 @@
|
|||
dist/
|
||||
node_modules/
|
||||
|
|
|
|||
15
dist/cult-cache.d.ts
vendored
Normal file
15
dist/cult-cache.d.ts
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import type { CacheBackingStore, CultCacheDocumentDefinition, CultCacheDocumentValue, CultCacheEnvelope } from "./types";
|
||||
export declare class CultCache {
|
||||
#private;
|
||||
registerDocumentType<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition): TDefinition;
|
||||
addBackingStore(store: CacheBackingStore, ...types: string[]): void;
|
||||
pullAllBackingStores(): Promise<void>;
|
||||
get<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition, key: string): CultCacheDocumentValue<TDefinition> | undefined;
|
||||
getRequired<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition, key: string): CultCacheDocumentValue<TDefinition>;
|
||||
getAll<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition): CultCacheDocumentValue<TDefinition>[];
|
||||
put<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition, key: string, value: CultCacheDocumentValue<TDefinition>): Promise<CultCacheDocumentValue<TDefinition>>;
|
||||
update<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition, key: string, updater: (current: CultCacheDocumentValue<TDefinition> | undefined) => CultCacheDocumentValue<TDefinition>): Promise<CultCacheDocumentValue<TDefinition>>;
|
||||
delete<TDefinition extends CultCacheDocumentDefinition>(definition: TDefinition, key: string): Promise<boolean>;
|
||||
snapshot(): CultCacheEnvelope[];
|
||||
}
|
||||
//# sourceMappingURL=cult-cache.d.ts.map
|
||||
1
dist/cult-cache.d.ts.map
vendored
Normal file
1
dist/cult-cache.d.ts.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"cult-cache.d.ts","sourceRoot":"","sources":["../src/cult-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,iBAAiB,EAElB,MAAM,SAAS,CAAC;AAOjB,qBAAa,SAAS;;IAKpB,oBAAoB,CAAC,WAAW,SAAS,2BAA2B,EAClE,UAAU,EAAE,WAAW,GACtB,WAAW;IAUd,eAAe,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAO7D,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3C,GAAG,CAAC,WAAW,SAAS,2BAA2B,EACjD,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,MAAM,GACV,sBAAsB,CAAC,WAAW,CAAC,GAAG,SAAS;IAMlD,WAAW,CAAC,WAAW,SAAS,2BAA2B,EACzD,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,MAAM,GACV,sBAAsB,CAAC,WAAW,CAAC;IAStC,MAAM,CAAC,WAAW,SAAS,2BAA2B,EACpD,UAAU,EAAE,WAAW,GACtB,sBAAsB,CAAC,WAAW,CAAC,EAAE;IAalC,GAAG,CAAC,WAAW,SAAS,2BAA2B,EACvD,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,sBAAsB,CAAC,WAAW,CAAC,GACzC,OAAO,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;IAqBzC,MAAM,CAAC,WAAW,SAAS,2BAA2B,EAC1D,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CACP,OAAO,EAAE,sBAAsB,CAAC,WAAW,CAAC,GAAG,SAAS,KACrD,sBAAsB,CAAC,WAAW,CAAC,GACvC,OAAO,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;IAKzC,MAAM,CAAC,WAAW,SAAS,2BAA2B,EAC1D,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC;IAkBnB,QAAQ,IAAI,iBAAiB,EAAE;CAkChC"}
|
||||
126
dist/cult-cache.js
vendored
Normal file
126
dist/cult-cache.js
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CultCache = void 0;
|
||||
class CultCache {
|
||||
#definitions = new Map();
|
||||
#entries = new Map();
|
||||
#stores = [];
|
||||
registerDocumentType(definition) {
|
||||
const existing = this.#definitions.get(definition.type);
|
||||
if (existing && existing !== definition) {
|
||||
throw new Error(`CultCache already has a different definition registered for type "${definition.type}".`);
|
||||
}
|
||||
this.#definitions.set(definition.type, definition);
|
||||
return definition;
|
||||
}
|
||||
addBackingStore(store, ...types) {
|
||||
this.#stores.push({
|
||||
store,
|
||||
types: [...new Set(types)],
|
||||
});
|
||||
}
|
||||
async pullAllBackingStores() {
|
||||
this.#entries.clear();
|
||||
for (const registration of this.#stores) {
|
||||
const entries = await registration.store.pullAll();
|
||||
for (const entry of entries) {
|
||||
const definition = this.#definitions.get(entry.type);
|
||||
if (!definition) {
|
||||
throw new Error(`No schema is registered for persisted document type "${entry.type}".`);
|
||||
}
|
||||
const parsed = definition.schema.parse(entry.payload);
|
||||
this.#entries.set(this.#entryId(entry.type, entry.key), {
|
||||
...entry,
|
||||
payload: parsed,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
get(definition, key) {
|
||||
this.#requireDefinition(definition);
|
||||
const entry = this.#entries.get(this.#entryId(definition.type, key));
|
||||
return entry ? entry.payload : undefined;
|
||||
}
|
||||
getRequired(definition, key) {
|
||||
const value = this.get(definition, key);
|
||||
if (value === undefined) {
|
||||
throw new Error(`CultCache has no "${definition.type}" document at key "${key}".`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
getAll(definition) {
|
||||
this.#requireDefinition(definition);
|
||||
const values = [];
|
||||
for (const entry of this.#entries.values()) {
|
||||
if (entry.type === definition.type) {
|
||||
values.push(entry.payload);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
async put(definition, key, value) {
|
||||
this.#requireDefinition(definition);
|
||||
const parsed = definition.schema.parse(value);
|
||||
const entry = {
|
||||
key,
|
||||
type: definition.type,
|
||||
payload: parsed,
|
||||
storedAt: new Date().toISOString(),
|
||||
};
|
||||
const route = this.#resolveRoute(definition.type);
|
||||
if (!route.primary) {
|
||||
throw new Error(`No backing store is registered for document type "${definition.type}".`);
|
||||
}
|
||||
await route.primary.push(entry);
|
||||
await Promise.all(route.mirrors.map(async (mirror) => mirror.push(entry)));
|
||||
this.#entries.set(this.#entryId(definition.type, key), entry);
|
||||
return parsed;
|
||||
}
|
||||
async update(definition, key, updater) {
|
||||
const current = this.get(definition, key);
|
||||
return this.put(definition, key, updater(current));
|
||||
}
|
||||
async delete(definition, key) {
|
||||
this.#requireDefinition(definition);
|
||||
const entry = this.#entries.get(this.#entryId(definition.type, key));
|
||||
if (!entry) {
|
||||
return false;
|
||||
}
|
||||
const route = this.#resolveRoute(definition.type);
|
||||
if (!route.primary) {
|
||||
throw new Error(`No backing store is registered for document type "${definition.type}".`);
|
||||
}
|
||||
await route.primary.delete(entry);
|
||||
await Promise.all(route.mirrors.map(async (mirror) => mirror.delete(entry)));
|
||||
this.#entries.delete(this.#entryId(definition.type, key));
|
||||
return true;
|
||||
}
|
||||
snapshot() {
|
||||
return [...this.#entries.values()].map((entry) => structuredClone(entry));
|
||||
}
|
||||
#requireDefinition(definition) {
|
||||
const registered = this.#definitions.get(definition.type);
|
||||
if (!registered || registered !== definition) {
|
||||
throw new Error(`CultCache document type "${definition.type}" is not registered on this cache instance.`);
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
#resolveRoute(type) {
|
||||
const typeSpecific = this.#stores.filter((registration) => registration.types.includes(type));
|
||||
if (typeSpecific.length > 0) {
|
||||
return {
|
||||
primary: typeSpecific[0]?.store,
|
||||
mirrors: typeSpecific.slice(1).map((registration) => registration.store),
|
||||
};
|
||||
}
|
||||
const generic = this.#stores.filter((registration) => registration.types.length === 0);
|
||||
return {
|
||||
primary: generic[0]?.store,
|
||||
mirrors: generic.slice(1).map((registration) => registration.store),
|
||||
};
|
||||
}
|
||||
#entryId(type, key) {
|
||||
return `${type}::${key}`;
|
||||
}
|
||||
}
|
||||
exports.CultCache = CultCache;
|
||||
4
dist/document.d.ts
vendored
Normal file
4
dist/document.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import type { ZodType } from "zod";
|
||||
import type { CultCacheDocumentDefinition } from "./types";
|
||||
export declare function defineDocumentType<TSchema extends ZodType>(definition: CultCacheDocumentDefinition<TSchema>): CultCacheDocumentDefinition<TSchema>;
|
||||
//# sourceMappingURL=document.d.ts.map
|
||||
1
dist/document.d.ts.map
vendored
Normal file
1
dist/document.d.ts.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAE3D,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,OAAO,EACxD,UAAU,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC/C,2BAA2B,CAAC,OAAO,CAAC,CAMtC"}
|
||||
9
dist/document.js
vendored
Normal file
9
dist/document.js
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.defineDocumentType = defineDocumentType;
|
||||
function defineDocumentType(definition) {
|
||||
if (!definition.type || definition.type.trim().length === 0) {
|
||||
throw new Error("CultCache document types must declare a non-empty type.");
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
5
dist/index.d.ts
vendored
Normal file
5
dist/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export { CultCache } from "./cult-cache";
|
||||
export { defineDocumentType } from "./document";
|
||||
export { SingleFileMessagePackBackingStore } from "./single-file-messagepack-backing-store";
|
||||
export type { CacheBackingStore, CultCacheDocumentDefinition, CultCacheDocumentValue, CultCacheEnvelope, CultCacheStoreRegistration, PushAllOptions, } from "./types";
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
dist/index.d.ts.map
vendored
Normal file
1
dist/index.d.ts.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,iCAAiC,EAAE,MAAM,yCAAyC,CAAC;AAC5F,YAAY,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,cAAc,GACf,MAAM,SAAS,CAAC"}
|
||||
9
dist/index.js
vendored
Normal file
9
dist/index.js
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SingleFileMessagePackBackingStore = exports.defineDocumentType = exports.CultCache = void 0;
|
||||
var cult_cache_1 = require("./cult-cache");
|
||||
Object.defineProperty(exports, "CultCache", { enumerable: true, get: function () { return cult_cache_1.CultCache; } });
|
||||
var document_1 = require("./document");
|
||||
Object.defineProperty(exports, "defineDocumentType", { enumerable: true, get: function () { return document_1.defineDocumentType; } });
|
||||
var single_file_messagepack_backing_store_1 = require("./single-file-messagepack-backing-store");
|
||||
Object.defineProperty(exports, "SingleFileMessagePackBackingStore", { enumerable: true, get: function () { return single_file_messagepack_backing_store_1.SingleFileMessagePackBackingStore; } });
|
||||
11
dist/single-file-messagepack-backing-store.d.ts
vendored
Normal file
11
dist/single-file-messagepack-backing-store.d.ts
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import type { CacheBackingStore, CultCacheEnvelope, PushAllOptions } from "./types";
|
||||
export declare class SingleFileMessagePackBackingStore implements CacheBackingStore {
|
||||
#private;
|
||||
readonly filePath: string;
|
||||
constructor(filePath: string);
|
||||
pullAll(): Promise<CultCacheEnvelope[]>;
|
||||
push(entry: CultCacheEnvelope): Promise<void>;
|
||||
delete(entry: CultCacheEnvelope): Promise<void>;
|
||||
pushAll(entries: CultCacheEnvelope[], options?: PushAllOptions): Promise<void>;
|
||||
}
|
||||
//# sourceMappingURL=single-file-messagepack-backing-store.d.ts.map
|
||||
1
dist/single-file-messagepack-backing-store.d.ts.map
vendored
Normal file
1
dist/single-file-messagepack-backing-store.d.ts.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"single-file-messagepack-backing-store.d.ts","sourceRoot":"","sources":["../src/single-file-messagepack-backing-store.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAWpF,qBAAa,iCAAkC,YAAW,iBAAiB;;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAId,QAAQ,EAAE,MAAM;IAItB,OAAO,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAcvC,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7C,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CAiDzF"}
|
||||
90
dist/single-file-messagepack-backing-store.js
vendored
Normal file
90
dist/single-file-messagepack-backing-store.js
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SingleFileMessagePackBackingStore = void 0;
|
||||
const promises_1 = require("node:fs/promises");
|
||||
const node_path_1 = require("node:path");
|
||||
const msgpack_1 = require("@msgpack/msgpack");
|
||||
const zod_1 = require("zod");
|
||||
const envelopeSchema = zod_1.z.object({
|
||||
key: zod_1.z.string().min(1),
|
||||
type: zod_1.z.string().min(1),
|
||||
payload: zod_1.z.unknown(),
|
||||
storedAt: zod_1.z.string().min(1),
|
||||
});
|
||||
const envelopeArraySchema = zod_1.z.array(envelopeSchema);
|
||||
class SingleFileMessagePackBackingStore {
|
||||
filePath;
|
||||
#writeQueue = Promise.resolve();
|
||||
constructor(filePath) {
|
||||
this.filePath = (0, node_path_1.resolve)(filePath);
|
||||
}
|
||||
async pullAll() {
|
||||
try {
|
||||
const data = await (0, promises_1.readFile)(this.filePath);
|
||||
return envelopeArraySchema.parse((0, msgpack_1.decode)(data));
|
||||
}
|
||||
catch (error) {
|
||||
const code = error.code;
|
||||
if (code === "ENOENT") {
|
||||
return [];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async push(entry) {
|
||||
await this.#enqueue(async () => {
|
||||
const existing = await this.pullAll();
|
||||
const filtered = existing.filter((candidate) => !(candidate.type === entry.type && candidate.key === entry.key));
|
||||
filtered.push(entry);
|
||||
await this.#writeAll(filtered);
|
||||
});
|
||||
}
|
||||
async delete(entry) {
|
||||
await this.#enqueue(async () => {
|
||||
const existing = await this.pullAll();
|
||||
const filtered = existing.filter((candidate) => !(candidate.type === entry.type && candidate.key === entry.key));
|
||||
await this.#writeAll(filtered);
|
||||
});
|
||||
}
|
||||
async pushAll(entries, options = {}) {
|
||||
await this.#enqueue(async () => {
|
||||
if (options.soft) {
|
||||
try {
|
||||
await (0, promises_1.readFile)(this.filePath);
|
||||
return;
|
||||
}
|
||||
catch (error) {
|
||||
const code = error.code;
|
||||
if (code !== "ENOENT") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.#writeAll(entries);
|
||||
});
|
||||
}
|
||||
async #enqueue(operation) {
|
||||
let result;
|
||||
const next = this.#writeQueue.then(async () => {
|
||||
result = await operation();
|
||||
});
|
||||
this.#writeQueue = next.then(() => undefined, () => undefined);
|
||||
await next;
|
||||
return result;
|
||||
}
|
||||
async #writeAll(entries) {
|
||||
await (0, promises_1.mkdir)((0, node_path_1.dirname)(this.filePath), { recursive: true });
|
||||
const tempPath = `${this.filePath}.tmp-${process.pid}-${Date.now()}-${Math.random()
|
||||
.toString(36)
|
||||
.slice(2)}`;
|
||||
try {
|
||||
await (0, promises_1.writeFile)(tempPath, (0, msgpack_1.encode)(entries));
|
||||
await (0, promises_1.rename)(tempPath, this.filePath);
|
||||
}
|
||||
catch (error) {
|
||||
await (0, promises_1.rm)(tempPath, { force: true }).catch(() => undefined);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.SingleFileMessagePackBackingStore = SingleFileMessagePackBackingStore;
|
||||
26
dist/types.d.ts
vendored
Normal file
26
dist/types.d.ts
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { z, type ZodType } from "zod";
|
||||
export interface CultCacheDocumentDefinition<TSchema extends ZodType = ZodType> {
|
||||
type: string;
|
||||
schema: TSchema;
|
||||
}
|
||||
export type CultCacheDocumentValue<TDefinition extends CultCacheDocumentDefinition> = z.infer<TDefinition["schema"]>;
|
||||
export interface CultCacheEnvelope {
|
||||
key: string;
|
||||
type: string;
|
||||
payload: unknown;
|
||||
storedAt: string;
|
||||
}
|
||||
export interface PushAllOptions {
|
||||
soft?: boolean;
|
||||
}
|
||||
export interface CacheBackingStore {
|
||||
pullAll(): Promise<CultCacheEnvelope[]>;
|
||||
push(entry: CultCacheEnvelope): Promise<void>;
|
||||
delete(entry: CultCacheEnvelope): Promise<void>;
|
||||
pushAll?(entries: CultCacheEnvelope[], options?: PushAllOptions): Promise<void>;
|
||||
}
|
||||
export interface CultCacheStoreRegistration {
|
||||
store: CacheBackingStore;
|
||||
types: string[];
|
||||
}
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
1
dist/types.d.ts.map
vendored
Normal file
1
dist/types.d.ts.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAEtC,MAAM,WAAW,2BAA2B,CAAC,OAAO,SAAS,OAAO,GAAG,OAAO;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,CAAC,WAAW,SAAS,2BAA2B,IAAI,CAAC,CAAC,KAAK,CAC3F,WAAW,CAAC,QAAQ,CAAC,CACtB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjF;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB"}
|
||||
2
dist/types.js
vendored
Normal file
2
dist/types.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
Loading…
Reference in a new issue