@xyo-network/schema-cache 2.107.3 → 2.107.4

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.
@@ -1,2 +1,136 @@
1
- var m=Object.defineProperty;var r=(a,t)=>m(a,"name",{value:t,configurable:!0});import{delay as f}from"@xylabs/delay";var c=class{static{r(this,"Debounce")}map=new Map;async one(t,e,i=1e4){let o=Date.now();for(;this.map.get(t);)if(await f(100),Date.now()-o>i)throw new Error(`Debounce timed out [${t}]`);try{return this.map.set(t,1),await e()}finally{this.map.set(t,0)}}};import{isAxiosError as l}from"@xylabs/axios";import{handleError as d}from"@xylabs/error";import{DomainPayloadWrapper as p}from"@xyo-network/domain-payload-plugin";import{SchemaSchema as s}from"@xyo-network/schema-payload-plugin";import u from"ajv";import{LRUCache as w}from"lru-cache";var g=r(a=>{if(a.$id)return a.$id},"getSchemaNameFromSchema"),n=class a{static{r(this,"SchemaCache")}static NULL={payload:{definition:{},schema:s}};static _instance;onSchemaCached;proxy;_cache=new w({max:500,ttl:1e3*60*5});_validators={};getDebounce=new c;constructor(t){this.proxy=t}static get instance(){return this._instance||(this._instance=new a),this._instance}get validators(){return this._validators}async get(t){if(t){await this.getDebounce.one(t,async()=>{this._cache.get(t)===void 0&&await this.fetchSchema(t)});let e=this._cache.get(t);return e===a.NULL?null:e}}cacheSchemaIfValid(t){if(t.payload.definition){let i=new u({strict:!1}).compile(t.payload.definition),o=g(t.payload.definition);if(o){this._cache.set(o,t);let h=o;this._validators[h]=i,this.onSchemaCached?.(o,t)}}}cacheSchemas(t){for(let e of t?.filter(i=>i.payload.schema===s)??[])this.cacheSchemaIfValid(e)}async fetchSchema(t){try{let e=await p.discover(t,this.proxy);await e?.fetch(),this.cacheSchemas(e?.aliases),this._cache.get(t)===void 0&&this._cache.set(t,a.NULL)}catch(e){this._cache.set(t,a.NULL),l(e)&&console.log(`Axios Url: ${e.response?.config.url}`),d(e,i=>{console.error(`fetchSchema threw: ${i.message}`)})}}};export{c as Debounce,n as SchemaCache};
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/Debounce.ts
5
+ import { delay } from "@xylabs/delay";
6
+ var Debounce = class {
7
+ static {
8
+ __name(this, "Debounce");
9
+ }
10
+ map = /* @__PURE__ */ new Map();
11
+ async one(key, closure, timeout = 1e4) {
12
+ const startTime = Date.now();
13
+ while (this.map.get(key)) {
14
+ await delay(100);
15
+ if (Date.now() - startTime > timeout) {
16
+ throw new Error(`Debounce timed out [${key}]`);
17
+ }
18
+ }
19
+ try {
20
+ this.map.set(key, 1);
21
+ return await closure();
22
+ } finally {
23
+ this.map.set(key, 0);
24
+ }
25
+ }
26
+ };
27
+
28
+ // src/SchemaCache.ts
29
+ import { isAxiosError } from "@xylabs/axios";
30
+ import { handleError } from "@xylabs/error";
31
+ import { DomainPayloadWrapper } from "@xyo-network/domain-payload-plugin";
32
+ import { SchemaSchema } from "@xyo-network/schema-payload-plugin";
33
+ import Ajv from "ajv";
34
+ import { LRUCache } from "lru-cache";
35
+ var getSchemaNameFromSchema = /* @__PURE__ */ __name((schema) => {
36
+ if (schema.$id) {
37
+ return schema.$id;
38
+ }
39
+ }, "getSchemaNameFromSchema");
40
+ var SchemaCache = class _SchemaCache {
41
+ static {
42
+ __name(this, "SchemaCache");
43
+ }
44
+ /**
45
+ * Object representing `null` since LRU Cache types
46
+ * only allow for types that derive from object
47
+ */
48
+ static NULL = {
49
+ payload: {
50
+ definition: {},
51
+ schema: SchemaSchema
52
+ }
53
+ };
54
+ static _instance;
55
+ onSchemaCached;
56
+ proxy;
57
+ _cache = new LRUCache({
58
+ max: 500,
59
+ ttl: 1e3 * 60 * 5
60
+ });
61
+ _validators = {};
62
+ //prevents double discovery
63
+ getDebounce = new Debounce();
64
+ constructor(proxy) {
65
+ this.proxy = proxy;
66
+ }
67
+ static get instance() {
68
+ if (!this._instance) {
69
+ this._instance = new _SchemaCache();
70
+ }
71
+ return this._instance;
72
+ }
73
+ /**
74
+ * A map of cached schema (by name) to payload validators for the schema. A schema
75
+ * must be cached via `get('schema.name')` before it's validator can be used as
76
+ * they are compiled dynamically at runtime upon retrieval.
77
+ */
78
+ get validators() {
79
+ return this._validators;
80
+ }
81
+ async get(schema) {
82
+ if (schema) {
83
+ await this.getDebounce.one(schema, async () => {
84
+ if (this._cache.get(schema) === void 0) {
85
+ await this.fetchSchema(schema);
86
+ }
87
+ });
88
+ const value = this._cache.get(schema);
89
+ return value === _SchemaCache.NULL ? null : value;
90
+ }
91
+ return void 0;
92
+ }
93
+ cacheSchemaIfValid(entry) {
94
+ if (entry.payload.definition) {
95
+ const ajv = new Ajv({
96
+ strict: false
97
+ });
98
+ const validator = ajv.compile(entry.payload.definition);
99
+ const schemaName = getSchemaNameFromSchema(entry.payload.definition);
100
+ if (schemaName) {
101
+ this._cache.set(schemaName, entry);
102
+ const key = schemaName;
103
+ this._validators[key] = validator;
104
+ this.onSchemaCached?.(schemaName, entry);
105
+ }
106
+ }
107
+ }
108
+ cacheSchemas(aliasEntries) {
109
+ for (const entry of aliasEntries?.filter((entry2) => entry2.payload.schema === SchemaSchema) ?? []) {
110
+ this.cacheSchemaIfValid(entry);
111
+ }
112
+ }
113
+ async fetchSchema(schema) {
114
+ try {
115
+ const domain = await DomainPayloadWrapper.discover(schema, this.proxy);
116
+ await domain?.fetch();
117
+ this.cacheSchemas(domain?.aliases);
118
+ if (this._cache.get(schema) === void 0) {
119
+ this._cache.set(schema, _SchemaCache.NULL);
120
+ }
121
+ } catch (error) {
122
+ this._cache.set(schema, _SchemaCache.NULL);
123
+ if (isAxiosError(error)) {
124
+ console.log(`Axios Url: ${error.response?.config.url}`);
125
+ }
126
+ handleError(error, (error2) => {
127
+ console.error(`fetchSchema threw: ${error2.message}`);
128
+ });
129
+ }
130
+ }
131
+ };
132
+ export {
133
+ Debounce,
134
+ SchemaCache
135
+ };
2
136
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Debounce.ts","../../src/SchemaCache.ts"],"sourcesContent":["import { delay } from '@xylabs/delay'\n\nexport class Debounce<TKey = string> {\n private map = new Map<TKey, number>()\n\n async one<T>(key: TKey, closure: () => Promise<T>, timeout = 10_000) {\n const startTime = Date.now()\n while (this.map.get(key)) {\n await delay(100)\n if (Date.now() - startTime > timeout) {\n throw new Error(`Debounce timed out [${key}]`)\n }\n }\n try {\n this.map.set(key, 1)\n return await closure()\n } finally {\n this.map.set(key, 0)\n }\n }\n}\n","import { isAxiosError } from '@xylabs/axios'\nimport { handleError } from '@xylabs/error'\nimport { DomainPayloadWrapper } from '@xyo-network/domain-payload-plugin'\nimport { FetchedPayload } from '@xyo-network/huri'\nimport { SchemaPayload, SchemaSchema } from '@xyo-network/schema-payload-plugin'\nimport Ajv, { SchemaObject } from 'ajv'\nimport { LRUCache } from 'lru-cache'\n\nimport { Debounce } from './Debounce'\nimport { SchemaNameToValidatorMap } from './SchemaNameToValidatorMap'\n\nconst getSchemaNameFromSchema = (schema: SchemaObject) => {\n if (schema.$id) {\n return schema.$id\n }\n}\n\nexport type SchemaCacheEntry = FetchedPayload<SchemaPayload>\n\nexport class SchemaCache<T extends SchemaNameToValidatorMap = SchemaNameToValidatorMap> {\n /**\n * Object representing `null` since LRU Cache types\n * only allow for types that derive from object\n */\n protected static readonly NULL: SchemaCacheEntry = { payload: { definition: {}, schema: SchemaSchema } }\n\n private static _instance?: SchemaCache\n\n onSchemaCached?: (name: string, entry: SchemaCacheEntry) => void\n proxy?: string\n\n private _cache = new LRUCache<string, SchemaCacheEntry>({ max: 500, ttl: 1000 * 60 * 5 })\n private _validators: T = {} as T\n\n //prevents double discovery\n private getDebounce = new Debounce()\n\n private constructor(proxy?: string) {\n this.proxy = proxy\n }\n\n static get instance() {\n if (!this._instance) {\n this._instance = new SchemaCache()\n }\n return this._instance\n }\n\n /**\n * A map of cached schema (by name) to payload validators for the schema. A schema\n * must be cached via `get('schema.name')` before it's validator can be used as\n * they are compiled dynamically at runtime upon retrieval.\n */\n get validators(): T {\n return this._validators\n }\n\n async get(schema?: string): Promise<SchemaCacheEntry | undefined | null> {\n if (schema) {\n await this.getDebounce.one(schema, async () => {\n // If we've never looked for it before, it will be undefined\n if (this._cache.get(schema) === undefined) {\n await this.fetchSchema(schema)\n }\n })\n const value = this._cache.get(schema)\n return value === SchemaCache.NULL ? null : value\n }\n return undefined\n }\n\n private cacheSchemaIfValid(entry: SchemaCacheEntry) {\n //only store them if they match the schema root\n if (entry.payload.definition) {\n const ajv = new Ajv({ strict: false })\n //check if it is a valid schema def\n const validator = ajv.compile(entry.payload.definition)\n const schemaName = getSchemaNameFromSchema(entry.payload.definition)\n if (schemaName) {\n this._cache.set(schemaName, entry)\n const key = schemaName as keyof T\n this._validators[key] = validator as unknown as T[keyof T]\n this.onSchemaCached?.(schemaName, entry)\n }\n }\n }\n\n private cacheSchemas(aliasEntries?: FetchedPayload[] | null) {\n for (const entry of aliasEntries?.filter((entry) => entry.payload.schema === SchemaSchema) ?? []) {\n this.cacheSchemaIfValid(entry as SchemaCacheEntry)\n }\n }\n\n private async fetchSchema(schema: string) {\n try {\n const domain = await DomainPayloadWrapper.discover(schema, this.proxy)\n await domain?.fetch()\n this.cacheSchemas(domain?.aliases)\n\n //if it is still undefined, mark it as null (not found)\n if (this._cache.get(schema) === undefined) {\n this._cache.set(schema, SchemaCache.NULL)\n }\n } catch (error) {\n //if failed, set it to NULL, TODO: Make an entry for an error to try again in the future?\n this._cache.set(schema, SchemaCache.NULL)\n if (isAxiosError(error)) {\n console.log(`Axios Url: ${error.response?.config.url}`)\n }\n handleError(error, (error) => {\n console.error(`fetchSchema threw: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["delay","Debounce","map","Map","one","key","closure","timeout","startTime","Date","now","get","delay","Error","set","isAxiosError","handleError","DomainPayloadWrapper","SchemaSchema","Ajv","LRUCache","getSchemaNameFromSchema","__name","schema","$id","SchemaCache","NULL","payload","definition","SchemaSchema","_instance","onSchemaCached","proxy","_cache","LRUCache","max","ttl","_validators","getDebounce","Debounce","instance","validators","get","one","undefined","fetchSchema","value","cacheSchemaIfValid","entry","validator","Ajv","strict","compile","schemaName","set","key","cacheSchemas","aliasEntries","filter","domain","DomainPayloadWrapper","discover","fetch","aliases","error","isAxiosError","console","log","response","config","url","handleError","message"]}
1
+ {"version":3,"sources":["../../src/Debounce.ts","../../src/SchemaCache.ts"],"sourcesContent":["import { delay } from '@xylabs/delay'\n\nexport class Debounce<TKey = string> {\n private map = new Map<TKey, number>()\n\n async one<T>(key: TKey, closure: () => Promise<T>, timeout = 10_000) {\n const startTime = Date.now()\n while (this.map.get(key)) {\n await delay(100)\n if (Date.now() - startTime > timeout) {\n throw new Error(`Debounce timed out [${key}]`)\n }\n }\n try {\n this.map.set(key, 1)\n return await closure()\n } finally {\n this.map.set(key, 0)\n }\n }\n}\n","import { isAxiosError } from '@xylabs/axios'\nimport { handleError } from '@xylabs/error'\nimport { DomainPayloadWrapper } from '@xyo-network/domain-payload-plugin'\nimport { FetchedPayload } from '@xyo-network/huri'\nimport { SchemaPayload, SchemaSchema } from '@xyo-network/schema-payload-plugin'\nimport Ajv, { SchemaObject } from 'ajv'\nimport { LRUCache } from 'lru-cache'\n\nimport { Debounce } from './Debounce'\nimport { SchemaNameToValidatorMap } from './SchemaNameToValidatorMap'\n\nconst getSchemaNameFromSchema = (schema: SchemaObject) => {\n if (schema.$id) {\n return schema.$id\n }\n}\n\nexport type SchemaCacheEntry = FetchedPayload<SchemaPayload>\n\nexport class SchemaCache<T extends SchemaNameToValidatorMap = SchemaNameToValidatorMap> {\n /**\n * Object representing `null` since LRU Cache types\n * only allow for types that derive from object\n */\n protected static readonly NULL: SchemaCacheEntry = { payload: { definition: {}, schema: SchemaSchema } }\n\n private static _instance?: SchemaCache\n\n onSchemaCached?: (name: string, entry: SchemaCacheEntry) => void\n proxy?: string\n\n private _cache = new LRUCache<string, SchemaCacheEntry>({ max: 500, ttl: 1000 * 60 * 5 })\n private _validators: T = {} as T\n\n //prevents double discovery\n private getDebounce = new Debounce()\n\n private constructor(proxy?: string) {\n this.proxy = proxy\n }\n\n static get instance() {\n if (!this._instance) {\n this._instance = new SchemaCache()\n }\n return this._instance\n }\n\n /**\n * A map of cached schema (by name) to payload validators for the schema. A schema\n * must be cached via `get('schema.name')` before it's validator can be used as\n * they are compiled dynamically at runtime upon retrieval.\n */\n get validators(): T {\n return this._validators\n }\n\n async get(schema?: string): Promise<SchemaCacheEntry | undefined | null> {\n if (schema) {\n await this.getDebounce.one(schema, async () => {\n // If we've never looked for it before, it will be undefined\n if (this._cache.get(schema) === undefined) {\n await this.fetchSchema(schema)\n }\n })\n const value = this._cache.get(schema)\n return value === SchemaCache.NULL ? null : value\n }\n return undefined\n }\n\n private cacheSchemaIfValid(entry: SchemaCacheEntry) {\n //only store them if they match the schema root\n if (entry.payload.definition) {\n const ajv = new Ajv({ strict: false })\n //check if it is a valid schema def\n const validator = ajv.compile(entry.payload.definition)\n const schemaName = getSchemaNameFromSchema(entry.payload.definition)\n if (schemaName) {\n this._cache.set(schemaName, entry)\n const key = schemaName as keyof T\n this._validators[key] = validator as unknown as T[keyof T]\n this.onSchemaCached?.(schemaName, entry)\n }\n }\n }\n\n private cacheSchemas(aliasEntries?: FetchedPayload[] | null) {\n for (const entry of aliasEntries?.filter((entry) => entry.payload.schema === SchemaSchema) ?? []) {\n this.cacheSchemaIfValid(entry as SchemaCacheEntry)\n }\n }\n\n private async fetchSchema(schema: string) {\n try {\n const domain = await DomainPayloadWrapper.discover(schema, this.proxy)\n await domain?.fetch()\n this.cacheSchemas(domain?.aliases)\n\n //if it is still undefined, mark it as null (not found)\n if (this._cache.get(schema) === undefined) {\n this._cache.set(schema, SchemaCache.NULL)\n }\n } catch (error) {\n //if failed, set it to NULL, TODO: Make an entry for an error to try again in the future?\n this._cache.set(schema, SchemaCache.NULL)\n if (isAxiosError(error)) {\n console.log(`Axios Url: ${error.response?.config.url}`)\n }\n handleError(error, (error) => {\n console.error(`fetchSchema threw: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["delay","Debounce","map","Map","one","key","closure","timeout","startTime","Date","now","get","delay","Error","set","isAxiosError","handleError","DomainPayloadWrapper","SchemaSchema","Ajv","LRUCache","getSchemaNameFromSchema","schema","$id","SchemaCache","NULL","payload","definition","SchemaSchema","_instance","onSchemaCached","proxy","_cache","LRUCache","max","ttl","_validators","getDebounce","Debounce","instance","validators","get","one","undefined","fetchSchema","value","cacheSchemaIfValid","entry","ajv","Ajv","strict","validator","compile","schemaName","set","key","cacheSchemas","aliasEntries","filter","domain","DomainPayloadWrapper","discover","fetch","aliases","error","isAxiosError","console","log","response","config","url","handleError","message"]}
@@ -1,2 +1,174 @@
1
- "use strict";var S=Object.create;var c=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var $=(o,t,e)=>t in o?c(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var s=(o,t)=>c(o,"name",{value:t,configurable:!0});var j=(o,t)=>{for(var e in t)c(o,e,{get:t[e],enumerable:!0})},d=(o,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of N(t))!D.call(o,a)&&a!==e&&c(o,a,{get:()=>t[a],enumerable:!(i=_(t,a))||i.enumerable});return o};var A=(o,t,e)=>(e=o!=null?S(U(o)):{},d(t||!o||!o.__esModule?c(e,"default",{value:o,enumerable:!0}):e,o)),b=o=>d(c({},"__esModule",{value:!0}),o);var f=(o,t,e)=>$(o,typeof t!="symbol"?t+"":t,e);var V={};j(V,{Debounce:()=>n,SchemaCache:()=>l});module.exports=b(V);var w=require("@xylabs/delay");var m=class m{map=new Map;async one(t,e,i=1e4){let a=Date.now();for(;this.map.get(t);)if(await(0,w.delay)(100),Date.now()-a>i)throw new Error(`Debounce timed out [${t}]`);try{return this.map.set(t,1),await e()}finally{this.map.set(t,0)}}};s(m,"Debounce");var n=m;var u=require("@xylabs/axios"),g=require("@xylabs/error"),y=require("@xyo-network/domain-payload-plugin"),p=require("@xyo-network/schema-payload-plugin"),x=A(require("ajv"),1),v=require("lru-cache");var I=s(o=>{if(o.$id)return o.$id},"getSchemaNameFromSchema"),r=class r{onSchemaCached;proxy;_cache=new v.LRUCache({max:500,ttl:1e3*60*5});_validators={};getDebounce=new n;constructor(t){this.proxy=t}static get instance(){return this._instance||(this._instance=new r),this._instance}get validators(){return this._validators}async get(t){if(t){await this.getDebounce.one(t,async()=>{this._cache.get(t)===void 0&&await this.fetchSchema(t)});let e=this._cache.get(t);return e===r.NULL?null:e}}cacheSchemaIfValid(t){var e;if(t.payload.definition){let a=new x.default({strict:!1}).compile(t.payload.definition),h=I(t.payload.definition);if(h){this._cache.set(h,t);let L=h;this._validators[L]=a,(e=this.onSchemaCached)==null||e.call(this,h,t)}}}cacheSchemas(t){for(let e of(t==null?void 0:t.filter(i=>i.payload.schema===p.SchemaSchema))??[])this.cacheSchemaIfValid(e)}async fetchSchema(t){var e;try{let i=await y.DomainPayloadWrapper.discover(t,this.proxy);await(i==null?void 0:i.fetch()),this.cacheSchemas(i==null?void 0:i.aliases),this._cache.get(t)===void 0&&this._cache.set(t,r.NULL)}catch(i){this._cache.set(t,r.NULL),(0,u.isAxiosError)(i)&&console.log(`Axios Url: ${(e=i.response)==null?void 0:e.config.url}`),(0,g.handleError)(i,a=>{console.error(`fetchSchema threw: ${a.message}`)})}}};s(r,"SchemaCache"),f(r,"NULL",{payload:{definition:{},schema:p.SchemaSchema}}),f(r,"_instance");var l=r;0&&(module.exports={Debounce,SchemaCache});
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
+
33
+ // src/index.ts
34
+ var src_exports = {};
35
+ __export(src_exports, {
36
+ Debounce: () => Debounce,
37
+ SchemaCache: () => SchemaCache
38
+ });
39
+ module.exports = __toCommonJS(src_exports);
40
+
41
+ // src/Debounce.ts
42
+ var import_delay = require("@xylabs/delay");
43
+ var _Debounce = class _Debounce {
44
+ map = /* @__PURE__ */ new Map();
45
+ async one(key, closure, timeout = 1e4) {
46
+ const startTime = Date.now();
47
+ while (this.map.get(key)) {
48
+ await (0, import_delay.delay)(100);
49
+ if (Date.now() - startTime > timeout) {
50
+ throw new Error(`Debounce timed out [${key}]`);
51
+ }
52
+ }
53
+ try {
54
+ this.map.set(key, 1);
55
+ return await closure();
56
+ } finally {
57
+ this.map.set(key, 0);
58
+ }
59
+ }
60
+ };
61
+ __name(_Debounce, "Debounce");
62
+ var Debounce = _Debounce;
63
+
64
+ // src/SchemaCache.ts
65
+ var import_axios = require("@xylabs/axios");
66
+ var import_error = require("@xylabs/error");
67
+ var import_domain_payload_plugin = require("@xyo-network/domain-payload-plugin");
68
+ var import_schema_payload_plugin = require("@xyo-network/schema-payload-plugin");
69
+ var import_ajv = __toESM(require("ajv"), 1);
70
+ var import_lru_cache = require("lru-cache");
71
+ var getSchemaNameFromSchema = /* @__PURE__ */ __name((schema) => {
72
+ if (schema.$id) {
73
+ return schema.$id;
74
+ }
75
+ }, "getSchemaNameFromSchema");
76
+ var _SchemaCache = class _SchemaCache {
77
+ onSchemaCached;
78
+ proxy;
79
+ _cache = new import_lru_cache.LRUCache({
80
+ max: 500,
81
+ ttl: 1e3 * 60 * 5
82
+ });
83
+ _validators = {};
84
+ //prevents double discovery
85
+ getDebounce = new Debounce();
86
+ constructor(proxy) {
87
+ this.proxy = proxy;
88
+ }
89
+ static get instance() {
90
+ if (!this._instance) {
91
+ this._instance = new _SchemaCache();
92
+ }
93
+ return this._instance;
94
+ }
95
+ /**
96
+ * A map of cached schema (by name) to payload validators for the schema. A schema
97
+ * must be cached via `get('schema.name')` before it's validator can be used as
98
+ * they are compiled dynamically at runtime upon retrieval.
99
+ */
100
+ get validators() {
101
+ return this._validators;
102
+ }
103
+ async get(schema) {
104
+ if (schema) {
105
+ await this.getDebounce.one(schema, async () => {
106
+ if (this._cache.get(schema) === void 0) {
107
+ await this.fetchSchema(schema);
108
+ }
109
+ });
110
+ const value = this._cache.get(schema);
111
+ return value === _SchemaCache.NULL ? null : value;
112
+ }
113
+ return void 0;
114
+ }
115
+ cacheSchemaIfValid(entry) {
116
+ var _a;
117
+ if (entry.payload.definition) {
118
+ const ajv = new import_ajv.default({
119
+ strict: false
120
+ });
121
+ const validator = ajv.compile(entry.payload.definition);
122
+ const schemaName = getSchemaNameFromSchema(entry.payload.definition);
123
+ if (schemaName) {
124
+ this._cache.set(schemaName, entry);
125
+ const key = schemaName;
126
+ this._validators[key] = validator;
127
+ (_a = this.onSchemaCached) == null ? void 0 : _a.call(this, schemaName, entry);
128
+ }
129
+ }
130
+ }
131
+ cacheSchemas(aliasEntries) {
132
+ for (const entry of (aliasEntries == null ? void 0 : aliasEntries.filter((entry2) => entry2.payload.schema === import_schema_payload_plugin.SchemaSchema)) ?? []) {
133
+ this.cacheSchemaIfValid(entry);
134
+ }
135
+ }
136
+ async fetchSchema(schema) {
137
+ var _a;
138
+ try {
139
+ const domain = await import_domain_payload_plugin.DomainPayloadWrapper.discover(schema, this.proxy);
140
+ await (domain == null ? void 0 : domain.fetch());
141
+ this.cacheSchemas(domain == null ? void 0 : domain.aliases);
142
+ if (this._cache.get(schema) === void 0) {
143
+ this._cache.set(schema, _SchemaCache.NULL);
144
+ }
145
+ } catch (error) {
146
+ this._cache.set(schema, _SchemaCache.NULL);
147
+ if ((0, import_axios.isAxiosError)(error)) {
148
+ console.log(`Axios Url: ${(_a = error.response) == null ? void 0 : _a.config.url}`);
149
+ }
150
+ (0, import_error.handleError)(error, (error2) => {
151
+ console.error(`fetchSchema threw: ${error2.message}`);
152
+ });
153
+ }
154
+ }
155
+ };
156
+ __name(_SchemaCache, "SchemaCache");
157
+ /**
158
+ * Object representing `null` since LRU Cache types
159
+ * only allow for types that derive from object
160
+ */
161
+ __publicField(_SchemaCache, "NULL", {
162
+ payload: {
163
+ definition: {},
164
+ schema: import_schema_payload_plugin.SchemaSchema
165
+ }
166
+ });
167
+ __publicField(_SchemaCache, "_instance");
168
+ var SchemaCache = _SchemaCache;
169
+ // Annotate the CommonJS export names for ESM import in node:
170
+ 0 && (module.exports = {
171
+ Debounce,
172
+ SchemaCache
173
+ });
2
174
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/Debounce.ts","../../src/SchemaCache.ts"],"sourcesContent":["export * from './Debounce'\nexport * from './SchemaCache'\nexport * from './SchemaNameToValidatorMap'\n","import { delay } from '@xylabs/delay'\n\nexport class Debounce<TKey = string> {\n private map = new Map<TKey, number>()\n\n async one<T>(key: TKey, closure: () => Promise<T>, timeout = 10_000) {\n const startTime = Date.now()\n while (this.map.get(key)) {\n await delay(100)\n if (Date.now() - startTime > timeout) {\n throw new Error(`Debounce timed out [${key}]`)\n }\n }\n try {\n this.map.set(key, 1)\n return await closure()\n } finally {\n this.map.set(key, 0)\n }\n }\n}\n","import { isAxiosError } from '@xylabs/axios'\nimport { handleError } from '@xylabs/error'\nimport { DomainPayloadWrapper } from '@xyo-network/domain-payload-plugin'\nimport { FetchedPayload } from '@xyo-network/huri'\nimport { SchemaPayload, SchemaSchema } from '@xyo-network/schema-payload-plugin'\nimport Ajv, { SchemaObject } from 'ajv'\nimport { LRUCache } from 'lru-cache'\n\nimport { Debounce } from './Debounce'\nimport { SchemaNameToValidatorMap } from './SchemaNameToValidatorMap'\n\nconst getSchemaNameFromSchema = (schema: SchemaObject) => {\n if (schema.$id) {\n return schema.$id\n }\n}\n\nexport type SchemaCacheEntry = FetchedPayload<SchemaPayload>\n\nexport class SchemaCache<T extends SchemaNameToValidatorMap = SchemaNameToValidatorMap> {\n /**\n * Object representing `null` since LRU Cache types\n * only allow for types that derive from object\n */\n protected static readonly NULL: SchemaCacheEntry = { payload: { definition: {}, schema: SchemaSchema } }\n\n private static _instance?: SchemaCache\n\n onSchemaCached?: (name: string, entry: SchemaCacheEntry) => void\n proxy?: string\n\n private _cache = new LRUCache<string, SchemaCacheEntry>({ max: 500, ttl: 1000 * 60 * 5 })\n private _validators: T = {} as T\n\n //prevents double discovery\n private getDebounce = new Debounce()\n\n private constructor(proxy?: string) {\n this.proxy = proxy\n }\n\n static get instance() {\n if (!this._instance) {\n this._instance = new SchemaCache()\n }\n return this._instance\n }\n\n /**\n * A map of cached schema (by name) to payload validators for the schema. A schema\n * must be cached via `get('schema.name')` before it's validator can be used as\n * they are compiled dynamically at runtime upon retrieval.\n */\n get validators(): T {\n return this._validators\n }\n\n async get(schema?: string): Promise<SchemaCacheEntry | undefined | null> {\n if (schema) {\n await this.getDebounce.one(schema, async () => {\n // If we've never looked for it before, it will be undefined\n if (this._cache.get(schema) === undefined) {\n await this.fetchSchema(schema)\n }\n })\n const value = this._cache.get(schema)\n return value === SchemaCache.NULL ? null : value\n }\n return undefined\n }\n\n private cacheSchemaIfValid(entry: SchemaCacheEntry) {\n //only store them if they match the schema root\n if (entry.payload.definition) {\n const ajv = new Ajv({ strict: false })\n //check if it is a valid schema def\n const validator = ajv.compile(entry.payload.definition)\n const schemaName = getSchemaNameFromSchema(entry.payload.definition)\n if (schemaName) {\n this._cache.set(schemaName, entry)\n const key = schemaName as keyof T\n this._validators[key] = validator as unknown as T[keyof T]\n this.onSchemaCached?.(schemaName, entry)\n }\n }\n }\n\n private cacheSchemas(aliasEntries?: FetchedPayload[] | null) {\n for (const entry of aliasEntries?.filter((entry) => entry.payload.schema === SchemaSchema) ?? []) {\n this.cacheSchemaIfValid(entry as SchemaCacheEntry)\n }\n }\n\n private async fetchSchema(schema: string) {\n try {\n const domain = await DomainPayloadWrapper.discover(schema, this.proxy)\n await domain?.fetch()\n this.cacheSchemas(domain?.aliases)\n\n //if it is still undefined, mark it as null (not found)\n if (this._cache.get(schema) === undefined) {\n this._cache.set(schema, SchemaCache.NULL)\n }\n } catch (error) {\n //if failed, set it to NULL, TODO: Make an entry for an error to try again in the future?\n this._cache.set(schema, SchemaCache.NULL)\n if (isAxiosError(error)) {\n console.log(`Axios Url: ${error.response?.config.url}`)\n }\n handleError(error, (error) => {\n console.error(`fetchSchema threw: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["src_exports","__export","Debounce","SchemaCache","__toCommonJS","import_delay","Debounce","map","Map","one","key","closure","timeout","startTime","Date","now","get","delay","Error","set","_Debounce","import_axios","import_error","import_domain_payload_plugin","import_schema_payload_plugin","import_ajv","import_lru_cache","getSchemaNameFromSchema","__name","schema","$id","SchemaCache","onSchemaCached","proxy","_cache","LRUCache","max","ttl","_validators","getDebounce","Debounce","instance","_instance","validators","get","one","undefined","fetchSchema","value","NULL","cacheSchemaIfValid","entry","_a","payload","definition","validator","Ajv","strict","compile","schemaName","set","key","cacheSchemas","aliasEntries","filter","SchemaSchema","domain","DomainPayloadWrapper","discover","fetch","aliases","error","isAxiosError","console","log","response","config","url","handleError","message","__publicField","_SchemaCache"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/Debounce.ts","../../src/SchemaCache.ts"],"sourcesContent":["export * from './Debounce'\nexport * from './SchemaCache'\nexport * from './SchemaNameToValidatorMap'\n","import { delay } from '@xylabs/delay'\n\nexport class Debounce<TKey = string> {\n private map = new Map<TKey, number>()\n\n async one<T>(key: TKey, closure: () => Promise<T>, timeout = 10_000) {\n const startTime = Date.now()\n while (this.map.get(key)) {\n await delay(100)\n if (Date.now() - startTime > timeout) {\n throw new Error(`Debounce timed out [${key}]`)\n }\n }\n try {\n this.map.set(key, 1)\n return await closure()\n } finally {\n this.map.set(key, 0)\n }\n }\n}\n","import { isAxiosError } from '@xylabs/axios'\nimport { handleError } from '@xylabs/error'\nimport { DomainPayloadWrapper } from '@xyo-network/domain-payload-plugin'\nimport { FetchedPayload } from '@xyo-network/huri'\nimport { SchemaPayload, SchemaSchema } from '@xyo-network/schema-payload-plugin'\nimport Ajv, { SchemaObject } from 'ajv'\nimport { LRUCache } from 'lru-cache'\n\nimport { Debounce } from './Debounce'\nimport { SchemaNameToValidatorMap } from './SchemaNameToValidatorMap'\n\nconst getSchemaNameFromSchema = (schema: SchemaObject) => {\n if (schema.$id) {\n return schema.$id\n }\n}\n\nexport type SchemaCacheEntry = FetchedPayload<SchemaPayload>\n\nexport class SchemaCache<T extends SchemaNameToValidatorMap = SchemaNameToValidatorMap> {\n /**\n * Object representing `null` since LRU Cache types\n * only allow for types that derive from object\n */\n protected static readonly NULL: SchemaCacheEntry = { payload: { definition: {}, schema: SchemaSchema } }\n\n private static _instance?: SchemaCache\n\n onSchemaCached?: (name: string, entry: SchemaCacheEntry) => void\n proxy?: string\n\n private _cache = new LRUCache<string, SchemaCacheEntry>({ max: 500, ttl: 1000 * 60 * 5 })\n private _validators: T = {} as T\n\n //prevents double discovery\n private getDebounce = new Debounce()\n\n private constructor(proxy?: string) {\n this.proxy = proxy\n }\n\n static get instance() {\n if (!this._instance) {\n this._instance = new SchemaCache()\n }\n return this._instance\n }\n\n /**\n * A map of cached schema (by name) to payload validators for the schema. A schema\n * must be cached via `get('schema.name')` before it's validator can be used as\n * they are compiled dynamically at runtime upon retrieval.\n */\n get validators(): T {\n return this._validators\n }\n\n async get(schema?: string): Promise<SchemaCacheEntry | undefined | null> {\n if (schema) {\n await this.getDebounce.one(schema, async () => {\n // If we've never looked for it before, it will be undefined\n if (this._cache.get(schema) === undefined) {\n await this.fetchSchema(schema)\n }\n })\n const value = this._cache.get(schema)\n return value === SchemaCache.NULL ? null : value\n }\n return undefined\n }\n\n private cacheSchemaIfValid(entry: SchemaCacheEntry) {\n //only store them if they match the schema root\n if (entry.payload.definition) {\n const ajv = new Ajv({ strict: false })\n //check if it is a valid schema def\n const validator = ajv.compile(entry.payload.definition)\n const schemaName = getSchemaNameFromSchema(entry.payload.definition)\n if (schemaName) {\n this._cache.set(schemaName, entry)\n const key = schemaName as keyof T\n this._validators[key] = validator as unknown as T[keyof T]\n this.onSchemaCached?.(schemaName, entry)\n }\n }\n }\n\n private cacheSchemas(aliasEntries?: FetchedPayload[] | null) {\n for (const entry of aliasEntries?.filter((entry) => entry.payload.schema === SchemaSchema) ?? []) {\n this.cacheSchemaIfValid(entry as SchemaCacheEntry)\n }\n }\n\n private async fetchSchema(schema: string) {\n try {\n const domain = await DomainPayloadWrapper.discover(schema, this.proxy)\n await domain?.fetch()\n this.cacheSchemas(domain?.aliases)\n\n //if it is still undefined, mark it as null (not found)\n if (this._cache.get(schema) === undefined) {\n this._cache.set(schema, SchemaCache.NULL)\n }\n } catch (error) {\n //if failed, set it to NULL, TODO: Make an entry for an error to try again in the future?\n this._cache.set(schema, SchemaCache.NULL)\n if (isAxiosError(error)) {\n console.log(`Axios Url: ${error.response?.config.url}`)\n }\n handleError(error, (error) => {\n console.error(`fetchSchema threw: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["Debounce","map","Map","one","key","closure","timeout","startTime","Date","now","get","delay","Error","set","getSchemaNameFromSchema","schema","$id","SchemaCache","onSchemaCached","proxy","_cache","LRUCache","max","ttl","_validators","getDebounce","Debounce","instance","_instance","validators","get","one","undefined","fetchSchema","value","NULL","cacheSchemaIfValid","entry","payload","definition","ajv","Ajv","strict","validator","compile","schemaName","set","key","cacheSchemas","aliasEntries","filter","SchemaSchema","domain","DomainPayloadWrapper","discover","fetch","aliases","error","isAxiosError","console","log","response","config","url","handleError","message"]}
@@ -1,2 +1,138 @@
1
- var m=Object.defineProperty;var w=(i,t,e)=>t in i?m(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var c=(i,t)=>m(i,"name",{value:t,configurable:!0});var h=(i,t,e)=>w(i,typeof t!="symbol"?t+"":t,e);import{delay as u}from"@xylabs/delay";var f=class f{map=new Map;async one(t,e,o=1e4){let r=Date.now();for(;this.map.get(t);)if(await u(100),Date.now()-r>o)throw new Error(`Debounce timed out [${t}]`);try{return this.map.set(t,1),await e()}finally{this.map.set(t,0)}}};c(f,"Debounce");var n=f;import{isAxiosError as g}from"@xylabs/axios";import{handleError as y}from"@xylabs/error";import{DomainPayloadWrapper as x}from"@xyo-network/domain-payload-plugin";import{SchemaSchema as p}from"@xyo-network/schema-payload-plugin";import v from"ajv";import{LRUCache as L}from"lru-cache";var S=c(i=>{if(i.$id)return i.$id},"getSchemaNameFromSchema"),a=class a{onSchemaCached;proxy;_cache=new L({max:500,ttl:1e3*60*5});_validators={};getDebounce=new n;constructor(t){this.proxy=t}static get instance(){return this._instance||(this._instance=new a),this._instance}get validators(){return this._validators}async get(t){if(t){await this.getDebounce.one(t,async()=>{this._cache.get(t)===void 0&&await this.fetchSchema(t)});let e=this._cache.get(t);return e===a.NULL?null:e}}cacheSchemaIfValid(t){var e;if(t.payload.definition){let r=new v({strict:!1}).compile(t.payload.definition),s=S(t.payload.definition);if(s){this._cache.set(s,t);let d=s;this._validators[d]=r,(e=this.onSchemaCached)==null||e.call(this,s,t)}}}cacheSchemas(t){for(let e of(t==null?void 0:t.filter(o=>o.payload.schema===p))??[])this.cacheSchemaIfValid(e)}async fetchSchema(t){var e;try{let o=await x.discover(t,this.proxy);await(o==null?void 0:o.fetch()),this.cacheSchemas(o==null?void 0:o.aliases),this._cache.get(t)===void 0&&this._cache.set(t,a.NULL)}catch(o){this._cache.set(t,a.NULL),g(o)&&console.log(`Axios Url: ${(e=o.response)==null?void 0:e.config.url}`),y(o,r=>{console.error(`fetchSchema threw: ${r.message}`)})}}};c(a,"SchemaCache"),h(a,"NULL",{payload:{definition:{},schema:p}}),h(a,"_instance");var l=a;export{n as Debounce,l as SchemaCache};
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+
6
+ // src/Debounce.ts
7
+ import { delay } from "@xylabs/delay";
8
+ var _Debounce = class _Debounce {
9
+ map = /* @__PURE__ */ new Map();
10
+ async one(key, closure, timeout = 1e4) {
11
+ const startTime = Date.now();
12
+ while (this.map.get(key)) {
13
+ await delay(100);
14
+ if (Date.now() - startTime > timeout) {
15
+ throw new Error(`Debounce timed out [${key}]`);
16
+ }
17
+ }
18
+ try {
19
+ this.map.set(key, 1);
20
+ return await closure();
21
+ } finally {
22
+ this.map.set(key, 0);
23
+ }
24
+ }
25
+ };
26
+ __name(_Debounce, "Debounce");
27
+ var Debounce = _Debounce;
28
+
29
+ // src/SchemaCache.ts
30
+ import { isAxiosError } from "@xylabs/axios";
31
+ import { handleError } from "@xylabs/error";
32
+ import { DomainPayloadWrapper } from "@xyo-network/domain-payload-plugin";
33
+ import { SchemaSchema } from "@xyo-network/schema-payload-plugin";
34
+ import Ajv from "ajv";
35
+ import { LRUCache } from "lru-cache";
36
+ var getSchemaNameFromSchema = /* @__PURE__ */ __name((schema) => {
37
+ if (schema.$id) {
38
+ return schema.$id;
39
+ }
40
+ }, "getSchemaNameFromSchema");
41
+ var _SchemaCache = class _SchemaCache {
42
+ onSchemaCached;
43
+ proxy;
44
+ _cache = new LRUCache({
45
+ max: 500,
46
+ ttl: 1e3 * 60 * 5
47
+ });
48
+ _validators = {};
49
+ //prevents double discovery
50
+ getDebounce = new Debounce();
51
+ constructor(proxy) {
52
+ this.proxy = proxy;
53
+ }
54
+ static get instance() {
55
+ if (!this._instance) {
56
+ this._instance = new _SchemaCache();
57
+ }
58
+ return this._instance;
59
+ }
60
+ /**
61
+ * A map of cached schema (by name) to payload validators for the schema. A schema
62
+ * must be cached via `get('schema.name')` before it's validator can be used as
63
+ * they are compiled dynamically at runtime upon retrieval.
64
+ */
65
+ get validators() {
66
+ return this._validators;
67
+ }
68
+ async get(schema) {
69
+ if (schema) {
70
+ await this.getDebounce.one(schema, async () => {
71
+ if (this._cache.get(schema) === void 0) {
72
+ await this.fetchSchema(schema);
73
+ }
74
+ });
75
+ const value = this._cache.get(schema);
76
+ return value === _SchemaCache.NULL ? null : value;
77
+ }
78
+ return void 0;
79
+ }
80
+ cacheSchemaIfValid(entry) {
81
+ var _a;
82
+ if (entry.payload.definition) {
83
+ const ajv = new Ajv({
84
+ strict: false
85
+ });
86
+ const validator = ajv.compile(entry.payload.definition);
87
+ const schemaName = getSchemaNameFromSchema(entry.payload.definition);
88
+ if (schemaName) {
89
+ this._cache.set(schemaName, entry);
90
+ const key = schemaName;
91
+ this._validators[key] = validator;
92
+ (_a = this.onSchemaCached) == null ? void 0 : _a.call(this, schemaName, entry);
93
+ }
94
+ }
95
+ }
96
+ cacheSchemas(aliasEntries) {
97
+ for (const entry of (aliasEntries == null ? void 0 : aliasEntries.filter((entry2) => entry2.payload.schema === SchemaSchema)) ?? []) {
98
+ this.cacheSchemaIfValid(entry);
99
+ }
100
+ }
101
+ async fetchSchema(schema) {
102
+ var _a;
103
+ try {
104
+ const domain = await DomainPayloadWrapper.discover(schema, this.proxy);
105
+ await (domain == null ? void 0 : domain.fetch());
106
+ this.cacheSchemas(domain == null ? void 0 : domain.aliases);
107
+ if (this._cache.get(schema) === void 0) {
108
+ this._cache.set(schema, _SchemaCache.NULL);
109
+ }
110
+ } catch (error) {
111
+ this._cache.set(schema, _SchemaCache.NULL);
112
+ if (isAxiosError(error)) {
113
+ console.log(`Axios Url: ${(_a = error.response) == null ? void 0 : _a.config.url}`);
114
+ }
115
+ handleError(error, (error2) => {
116
+ console.error(`fetchSchema threw: ${error2.message}`);
117
+ });
118
+ }
119
+ }
120
+ };
121
+ __name(_SchemaCache, "SchemaCache");
122
+ /**
123
+ * Object representing `null` since LRU Cache types
124
+ * only allow for types that derive from object
125
+ */
126
+ __publicField(_SchemaCache, "NULL", {
127
+ payload: {
128
+ definition: {},
129
+ schema: SchemaSchema
130
+ }
131
+ });
132
+ __publicField(_SchemaCache, "_instance");
133
+ var SchemaCache = _SchemaCache;
134
+ export {
135
+ Debounce,
136
+ SchemaCache
137
+ };
2
138
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Debounce.ts","../../src/SchemaCache.ts"],"sourcesContent":["import { delay } from '@xylabs/delay'\n\nexport class Debounce<TKey = string> {\n private map = new Map<TKey, number>()\n\n async one<T>(key: TKey, closure: () => Promise<T>, timeout = 10_000) {\n const startTime = Date.now()\n while (this.map.get(key)) {\n await delay(100)\n if (Date.now() - startTime > timeout) {\n throw new Error(`Debounce timed out [${key}]`)\n }\n }\n try {\n this.map.set(key, 1)\n return await closure()\n } finally {\n this.map.set(key, 0)\n }\n }\n}\n","import { isAxiosError } from '@xylabs/axios'\nimport { handleError } from '@xylabs/error'\nimport { DomainPayloadWrapper } from '@xyo-network/domain-payload-plugin'\nimport { FetchedPayload } from '@xyo-network/huri'\nimport { SchemaPayload, SchemaSchema } from '@xyo-network/schema-payload-plugin'\nimport Ajv, { SchemaObject } from 'ajv'\nimport { LRUCache } from 'lru-cache'\n\nimport { Debounce } from './Debounce'\nimport { SchemaNameToValidatorMap } from './SchemaNameToValidatorMap'\n\nconst getSchemaNameFromSchema = (schema: SchemaObject) => {\n if (schema.$id) {\n return schema.$id\n }\n}\n\nexport type SchemaCacheEntry = FetchedPayload<SchemaPayload>\n\nexport class SchemaCache<T extends SchemaNameToValidatorMap = SchemaNameToValidatorMap> {\n /**\n * Object representing `null` since LRU Cache types\n * only allow for types that derive from object\n */\n protected static readonly NULL: SchemaCacheEntry = { payload: { definition: {}, schema: SchemaSchema } }\n\n private static _instance?: SchemaCache\n\n onSchemaCached?: (name: string, entry: SchemaCacheEntry) => void\n proxy?: string\n\n private _cache = new LRUCache<string, SchemaCacheEntry>({ max: 500, ttl: 1000 * 60 * 5 })\n private _validators: T = {} as T\n\n //prevents double discovery\n private getDebounce = new Debounce()\n\n private constructor(proxy?: string) {\n this.proxy = proxy\n }\n\n static get instance() {\n if (!this._instance) {\n this._instance = new SchemaCache()\n }\n return this._instance\n }\n\n /**\n * A map of cached schema (by name) to payload validators for the schema. A schema\n * must be cached via `get('schema.name')` before it's validator can be used as\n * they are compiled dynamically at runtime upon retrieval.\n */\n get validators(): T {\n return this._validators\n }\n\n async get(schema?: string): Promise<SchemaCacheEntry | undefined | null> {\n if (schema) {\n await this.getDebounce.one(schema, async () => {\n // If we've never looked for it before, it will be undefined\n if (this._cache.get(schema) === undefined) {\n await this.fetchSchema(schema)\n }\n })\n const value = this._cache.get(schema)\n return value === SchemaCache.NULL ? null : value\n }\n return undefined\n }\n\n private cacheSchemaIfValid(entry: SchemaCacheEntry) {\n //only store them if they match the schema root\n if (entry.payload.definition) {\n const ajv = new Ajv({ strict: false })\n //check if it is a valid schema def\n const validator = ajv.compile(entry.payload.definition)\n const schemaName = getSchemaNameFromSchema(entry.payload.definition)\n if (schemaName) {\n this._cache.set(schemaName, entry)\n const key = schemaName as keyof T\n this._validators[key] = validator as unknown as T[keyof T]\n this.onSchemaCached?.(schemaName, entry)\n }\n }\n }\n\n private cacheSchemas(aliasEntries?: FetchedPayload[] | null) {\n for (const entry of aliasEntries?.filter((entry) => entry.payload.schema === SchemaSchema) ?? []) {\n this.cacheSchemaIfValid(entry as SchemaCacheEntry)\n }\n }\n\n private async fetchSchema(schema: string) {\n try {\n const domain = await DomainPayloadWrapper.discover(schema, this.proxy)\n await domain?.fetch()\n this.cacheSchemas(domain?.aliases)\n\n //if it is still undefined, mark it as null (not found)\n if (this._cache.get(schema) === undefined) {\n this._cache.set(schema, SchemaCache.NULL)\n }\n } catch (error) {\n //if failed, set it to NULL, TODO: Make an entry for an error to try again in the future?\n this._cache.set(schema, SchemaCache.NULL)\n if (isAxiosError(error)) {\n console.log(`Axios Url: ${error.response?.config.url}`)\n }\n handleError(error, (error) => {\n console.error(`fetchSchema threw: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["delay","Debounce","map","Map","one","key","closure","timeout","startTime","Date","now","get","delay","Error","set","_Debounce","isAxiosError","handleError","DomainPayloadWrapper","SchemaSchema","Ajv","LRUCache","getSchemaNameFromSchema","__name","schema","$id","SchemaCache","onSchemaCached","proxy","_cache","LRUCache","max","ttl","_validators","getDebounce","Debounce","instance","_instance","validators","get","one","undefined","fetchSchema","value","NULL","cacheSchemaIfValid","entry","_a","payload","definition","validator","Ajv","strict","compile","schemaName","set","key","cacheSchemas","aliasEntries","filter","SchemaSchema","domain","DomainPayloadWrapper","discover","fetch","aliases","error","isAxiosError","console","log","response","config","url","handleError","message","__publicField","_SchemaCache"]}
1
+ {"version":3,"sources":["../../src/Debounce.ts","../../src/SchemaCache.ts"],"sourcesContent":["import { delay } from '@xylabs/delay'\n\nexport class Debounce<TKey = string> {\n private map = new Map<TKey, number>()\n\n async one<T>(key: TKey, closure: () => Promise<T>, timeout = 10_000) {\n const startTime = Date.now()\n while (this.map.get(key)) {\n await delay(100)\n if (Date.now() - startTime > timeout) {\n throw new Error(`Debounce timed out [${key}]`)\n }\n }\n try {\n this.map.set(key, 1)\n return await closure()\n } finally {\n this.map.set(key, 0)\n }\n }\n}\n","import { isAxiosError } from '@xylabs/axios'\nimport { handleError } from '@xylabs/error'\nimport { DomainPayloadWrapper } from '@xyo-network/domain-payload-plugin'\nimport { FetchedPayload } from '@xyo-network/huri'\nimport { SchemaPayload, SchemaSchema } from '@xyo-network/schema-payload-plugin'\nimport Ajv, { SchemaObject } from 'ajv'\nimport { LRUCache } from 'lru-cache'\n\nimport { Debounce } from './Debounce'\nimport { SchemaNameToValidatorMap } from './SchemaNameToValidatorMap'\n\nconst getSchemaNameFromSchema = (schema: SchemaObject) => {\n if (schema.$id) {\n return schema.$id\n }\n}\n\nexport type SchemaCacheEntry = FetchedPayload<SchemaPayload>\n\nexport class SchemaCache<T extends SchemaNameToValidatorMap = SchemaNameToValidatorMap> {\n /**\n * Object representing `null` since LRU Cache types\n * only allow for types that derive from object\n */\n protected static readonly NULL: SchemaCacheEntry = { payload: { definition: {}, schema: SchemaSchema } }\n\n private static _instance?: SchemaCache\n\n onSchemaCached?: (name: string, entry: SchemaCacheEntry) => void\n proxy?: string\n\n private _cache = new LRUCache<string, SchemaCacheEntry>({ max: 500, ttl: 1000 * 60 * 5 })\n private _validators: T = {} as T\n\n //prevents double discovery\n private getDebounce = new Debounce()\n\n private constructor(proxy?: string) {\n this.proxy = proxy\n }\n\n static get instance() {\n if (!this._instance) {\n this._instance = new SchemaCache()\n }\n return this._instance\n }\n\n /**\n * A map of cached schema (by name) to payload validators for the schema. A schema\n * must be cached via `get('schema.name')` before it's validator can be used as\n * they are compiled dynamically at runtime upon retrieval.\n */\n get validators(): T {\n return this._validators\n }\n\n async get(schema?: string): Promise<SchemaCacheEntry | undefined | null> {\n if (schema) {\n await this.getDebounce.one(schema, async () => {\n // If we've never looked for it before, it will be undefined\n if (this._cache.get(schema) === undefined) {\n await this.fetchSchema(schema)\n }\n })\n const value = this._cache.get(schema)\n return value === SchemaCache.NULL ? null : value\n }\n return undefined\n }\n\n private cacheSchemaIfValid(entry: SchemaCacheEntry) {\n //only store them if they match the schema root\n if (entry.payload.definition) {\n const ajv = new Ajv({ strict: false })\n //check if it is a valid schema def\n const validator = ajv.compile(entry.payload.definition)\n const schemaName = getSchemaNameFromSchema(entry.payload.definition)\n if (schemaName) {\n this._cache.set(schemaName, entry)\n const key = schemaName as keyof T\n this._validators[key] = validator as unknown as T[keyof T]\n this.onSchemaCached?.(schemaName, entry)\n }\n }\n }\n\n private cacheSchemas(aliasEntries?: FetchedPayload[] | null) {\n for (const entry of aliasEntries?.filter((entry) => entry.payload.schema === SchemaSchema) ?? []) {\n this.cacheSchemaIfValid(entry as SchemaCacheEntry)\n }\n }\n\n private async fetchSchema(schema: string) {\n try {\n const domain = await DomainPayloadWrapper.discover(schema, this.proxy)\n await domain?.fetch()\n this.cacheSchemas(domain?.aliases)\n\n //if it is still undefined, mark it as null (not found)\n if (this._cache.get(schema) === undefined) {\n this._cache.set(schema, SchemaCache.NULL)\n }\n } catch (error) {\n //if failed, set it to NULL, TODO: Make an entry for an error to try again in the future?\n this._cache.set(schema, SchemaCache.NULL)\n if (isAxiosError(error)) {\n console.log(`Axios Url: ${error.response?.config.url}`)\n }\n handleError(error, (error) => {\n console.error(`fetchSchema threw: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["delay","Debounce","map","Map","one","key","closure","timeout","startTime","Date","now","get","delay","Error","set","isAxiosError","handleError","DomainPayloadWrapper","SchemaSchema","Ajv","LRUCache","getSchemaNameFromSchema","schema","$id","SchemaCache","onSchemaCached","proxy","_cache","LRUCache","max","ttl","_validators","getDebounce","Debounce","instance","_instance","validators","get","one","undefined","fetchSchema","value","NULL","cacheSchemaIfValid","entry","payload","definition","ajv","Ajv","strict","validator","compile","schemaName","set","key","cacheSchemas","aliasEntries","filter","SchemaSchema","domain","DomainPayloadWrapper","discover","fetch","aliases","error","isAxiosError","console","log","response","config","url","handleError","message"]}