@nditure/gania 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -28,17 +28,21 @@ module.exports = __toCommonJS(index_exports);
28
28
 
29
29
  // src/cache/gania-cache.ts
30
30
  var GaniaCache = class {
31
- constructor(dbName, version = 1) {
32
- this.dbName = dbName;
33
- this.version = version;
34
- }
35
- dbName;
36
- version;
37
31
  db = null;
32
+ storeNames = [
33
+ "responses",
34
+ "mutations"
35
+ ];
36
+ DB_NAME = "ganiadb";
37
+ VERSION = 1;
38
38
  ramCache = /* @__PURE__ */ new Map();
39
39
  hydratedStores = /* @__PURE__ */ new Set();
40
40
  activeHydrations = /* @__PURE__ */ new Map();
41
41
  channel = null;
42
+ ready;
43
+ constructor() {
44
+ this.ready = this.#init();
45
+ }
42
46
  getDatabase() {
43
47
  if (!this.db) {
44
48
  throw new Error("GaniaCache has not been initialized.");
@@ -52,12 +56,12 @@ var GaniaCache = class {
52
56
  }
53
57
  return map;
54
58
  }
55
- async init(storeNames) {
59
+ async #init() {
56
60
  return new Promise((resolve, reject) => {
57
- const request = indexedDB.open(this.dbName, this.version);
61
+ const request = indexedDB.open(this.DB_NAME, this.VERSION);
58
62
  request.onupgradeneeded = () => {
59
63
  const db = request.result;
60
- for (const storeName of storeNames) {
64
+ for (const storeName of this.storeNames) {
61
65
  if (!db.objectStoreNames.contains(storeName)) {
62
66
  db.createObjectStore(storeName);
63
67
  }
@@ -65,10 +69,10 @@ var GaniaCache = class {
65
69
  };
66
70
  request.onsuccess = () => {
67
71
  this.db = request.result;
68
- for (const storeName of storeNames) {
72
+ for (const storeName of this.storeNames) {
69
73
  this.ramCache.set(storeName, /* @__PURE__ */ new Map());
70
74
  }
71
- this.channel = new BroadcastChannel(`gania-cache:${this.dbName}`);
75
+ this.channel = new BroadcastChannel(`gania-cache:${this.DB_NAME}`);
72
76
  this.channel.onmessage = (event) => this.handleBroadcast(event.data);
73
77
  resolve(this);
74
78
  };
@@ -135,6 +139,7 @@ var GaniaCache = class {
135
139
  }
136
140
  }
137
141
  async get(store, key) {
142
+ await this.ready;
138
143
  const storeMap = this.getStoreMap(store);
139
144
  if (storeMap.has(key)) {
140
145
  return storeMap.get(key) ?? null;
@@ -154,6 +159,7 @@ var GaniaCache = class {
154
159
  });
155
160
  }
156
161
  async set(store, key, value) {
162
+ await this.ready;
157
163
  const storeMap = this.getStoreMap(store);
158
164
  storeMap.set(key, value);
159
165
  const db = this.getDatabase();
@@ -171,6 +177,7 @@ var GaniaCache = class {
171
177
  });
172
178
  }
173
179
  async delete(store, key) {
180
+ await this.ready;
174
181
  this.getStoreMap(store).delete(key);
175
182
  const db = this.getDatabase();
176
183
  await new Promise((resolve, reject) => {
@@ -186,6 +193,7 @@ var GaniaCache = class {
186
193
  });
187
194
  }
188
195
  async clear(store) {
196
+ await this.ready;
189
197
  this.getStoreMap(store).clear();
190
198
  const db = this.getDatabase();
191
199
  await new Promise((resolve, reject) => {
@@ -200,16 +208,20 @@ var GaniaCache = class {
200
208
  });
201
209
  }
202
210
  async keys(store) {
211
+ await this.ready;
203
212
  await this.hydrateStore(store);
204
213
  return Array.from(this.getStoreMap(store).keys());
205
214
  }
206
215
  async entries(store) {
216
+ await this.ready;
207
217
  await this.hydrateStore(store);
208
218
  return Array.from(this.getStoreMap(store).entries());
209
219
  }
210
- destroy() {
220
+ async destroy() {
211
221
  this.channel?.close();
222
+ this.db?.close();
212
223
  this.channel = null;
224
+ this.db = null;
213
225
  }
214
226
  };
215
227
 
@@ -256,7 +268,7 @@ var Gania = class {
256
268
  gdb;
257
269
  constructor(options) {
258
270
  this.online = navigator.onLine;
259
- this.gdb = new GaniaCache("ganiadb");
271
+ this.gdb = new GaniaCache();
260
272
  this.baseUrl = options?.baseUrl;
261
273
  }
262
274
  async request({
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cache/gania-cache.ts","../src/response.ts","../src/gania.ts","../src/create.ts"],"sourcesContent":["import { create } from \"./create\";\r\n\r\nconst gania = create();\r\n\r\nexport default gania\r\n\r\nexport { default as Gania } from \"./gania\";\r\nexport { create };\r\nexport * from \"./types\"\r\n","type CacheEvent =\r\n | {\r\n type: \"set\";\r\n store: string;\r\n key: IDBValidKey;\r\n value: unknown;\r\n }\r\n | {\r\n type: \"delete\";\r\n store: string;\r\n key: IDBValidKey;\r\n }\r\n | {\r\n type: \"clear\";\r\n store: string;\r\n };\r\n\r\ntype StoreDef<K = unknown, V = unknown> = {\r\n key: K;\r\n value: V;\r\n};\r\nexport type CacheSchema<T> = { [K in keyof T]: StoreDef };\r\n\r\nexport class GaniaCache<Schema extends CacheSchema<Schema>> {\r\n private db: IDBDatabase | null = null;\r\n\r\n private readonly ramCache = new Map<keyof Schema, Map<unknown, unknown>>();\r\n\r\n private readonly hydratedStores = new Set<keyof Schema>();\r\n\r\n private readonly activeHydrations = new Map<keyof Schema, Promise<void>>();\r\n\r\n private channel: BroadcastChannel | null = null;\r\n\r\n constructor(\r\n private readonly dbName: string,\r\n private readonly version = 1,\r\n ) {}\r\n\r\n private getDatabase(): IDBDatabase {\r\n if (!this.db) {\r\n throw new Error(\"GaniaCache has not been initialized.\");\r\n }\r\n\r\n return this.db;\r\n }\r\n\r\n private getStoreMap<K extends keyof Schema>(\r\n store: K,\r\n ): Map<Schema[K][\"key\"], Schema[K][\"value\"]> {\r\n const map = this.ramCache.get(store);\r\n\r\n if (!map) {\r\n throw new Error(`Store \"${String(store)}\" is not initialized.`);\r\n }\r\n\r\n return map as Map<Schema[K][\"key\"], Schema[K][\"value\"]>;\r\n }\r\n\r\n async init(storeNames: (keyof Schema & string)[]): Promise<this> {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, this.version);\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result;\r\n\r\n for (const storeName of storeNames) {\r\n if (!db.objectStoreNames.contains(storeName)) {\r\n db.createObjectStore(storeName);\r\n }\r\n }\r\n };\r\n\r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n\r\n for (const storeName of storeNames) {\r\n this.ramCache.set(storeName, new Map());\r\n }\r\n\r\n this.channel = new BroadcastChannel(`gania-cache:${this.dbName}`);\r\n\r\n this.channel.onmessage = (event) => this.handleBroadcast(event.data);\r\n\r\n resolve(this);\r\n };\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n private handleBroadcast(event: CacheEvent) {\r\n const storeMap = this.ramCache.get(event.store as keyof Schema);\r\n\r\n if (!storeMap) return;\r\n\r\n switch (event.type) {\r\n case \"set\":\r\n storeMap.set(event.key, event.value);\r\n break;\r\n\r\n case \"delete\":\r\n storeMap.delete(event.key);\r\n break;\r\n\r\n case \"clear\":\r\n storeMap.clear();\r\n break;\r\n }\r\n }\r\n\r\n private broadcast(event: CacheEvent) {\r\n this.channel?.postMessage(event);\r\n }\r\n private async performHydration<K extends keyof Schema>(\r\n store: K,\r\n ): Promise<void> {\r\n const db = this.getDatabase();\r\n\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const objectStore = tx.objectStore(store as string);\r\n\r\n const [keys, values] = await Promise.all([\r\n new Promise<IDBValidKey[]>((resolve, reject) => {\r\n const req = objectStore.getAllKeys();\r\n\r\n req.onsuccess = () => resolve(req.result as IDBValidKey[]);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n\r\n new Promise<unknown[]>((resolve, reject) => {\r\n const req = objectStore.getAll();\r\n\r\n req.onsuccess = () => resolve(req.result);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n ]);\r\n\r\n const storeMap = this.getStoreMap(store);\r\n\r\n keys.forEach((key, index) => {\r\n storeMap.set(\r\n key as Schema[K][\"key\"],\r\n values[index] as Schema[K][\"value\"],\r\n );\r\n });\r\n\r\n this.hydratedStores.add(store);\r\n }\r\n private async hydrateStore<K extends keyof Schema>(store: K): Promise<void> {\r\n // Already hydrated\r\n if (this.hydratedStores.has(store)) {\r\n return;\r\n }\r\n\r\n // Hydration currently in progress\r\n const activeHydration = this.activeHydrations.get(store);\r\n\r\n if (activeHydration) {\r\n return activeHydration;\r\n }\r\n\r\n const hydrationPromise = this.performHydration(store);\r\n\r\n this.activeHydrations.set(store, hydrationPromise);\r\n\r\n try {\r\n await hydrationPromise;\r\n } finally {\r\n this.activeHydrations.delete(store);\r\n }\r\n }\r\n\r\n async get<K extends keyof Schema>(\r\n store: K,\r\n key: Schema[K][\"key\"],\r\n ): Promise<Schema[K][\"value\"] | null> {\r\n const storeMap = this.getStoreMap(store);\r\n\r\n if (storeMap.has(key)) {\r\n return storeMap.get(key) ?? null;\r\n }\r\n\r\n const db = this.getDatabase();\r\n\r\n return new Promise((resolve) => {\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const request = tx.objectStore(store as string).get(key as IDBValidKey);\r\n\r\n request.onsuccess = () => {\r\n const value = request.result ?? null;\r\n\r\n if (value !== null) {\r\n storeMap.set(key, value);\r\n }\r\n\r\n resolve(value as Schema[K][\"value\"] | null);\r\n };\r\n\r\n request.onerror = () => resolve(null);\r\n });\r\n }\r\n\r\n async set<K extends keyof Schema>(\r\n store: K,\r\n key: Schema[K][\"key\"],\r\n value: Schema[K][\"value\"],\r\n ): Promise<void> {\r\n const storeMap = this.getStoreMap(store);\r\n\r\n storeMap.set(key, value);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .put(value, key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"set\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n value,\r\n });\r\n }\r\n\r\n async delete<K extends keyof Schema>(\r\n store: K,\r\n key: Schema[K][\"key\"],\r\n ): Promise<void> {\r\n this.getStoreMap(store).delete(key);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .delete(key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"delete\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n });\r\n }\r\n\r\n async clear<K extends keyof Schema>(store: K): Promise<void> {\r\n this.getStoreMap(store).clear();\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx.objectStore(store as string).clear();\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"clear\",\r\n store: String(store),\r\n });\r\n }\r\n\r\n async keys<K extends keyof Schema>(store: K): Promise<Schema[K][\"key\"][]> {\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).keys());\r\n }\r\n\r\n async entries<K extends keyof Schema>(\r\n store: K,\r\n ): Promise<[Schema[K][\"key\"], Schema[K][\"value\"]][]> {\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).entries());\r\n }\r\n\r\n destroy() {\r\n this.channel?.close();\r\n this.channel = null;\r\n }\r\n}\r\n","import { GaniaResponse, ResponseDataType } from \"./types\";\r\n\r\nexport class GaniaError<T = any> extends Error {\r\n response?: GaniaResponse<T>;\r\n\r\n constructor(message: string, response?: GaniaResponse<T>) {\r\n super(message);\r\n this.name = \"GaniaError\";\r\n this.response = response;\r\n }\r\n}\r\n\r\nexport async function getResponseData<T = any>(\r\n response: Response,\r\n dataType: ResponseDataType = \"json\",\r\n): Promise<{ data: T; dataType: ResponseDataType }> {\r\n // Handle explicit types safely without unsafe dynamic property lookups\r\n if (dataType !== \"flexible\") {\r\n let data: any;\r\n if (dataType === \"json\") data = await response.json();\r\n else if (dataType === \"text\") data = await response.text();\r\n else if (dataType === \"blob\") data = await response.blob();\r\n else if (dataType === \"bytes\") {\r\n const buffer = await response.arrayBuffer();\r\n data = new Uint8Array(buffer);\r\n }\r\n return { data, dataType };\r\n }\r\n\r\n // Handle the 'flexible' inferred fallback chain correctly\r\n try {\r\n const data = await response.json();\r\n return { data, dataType: \"json\" };\r\n } catch {\r\n try {\r\n const data = await response.text() as T;\r\n return { data, dataType: \"text\" };\r\n } catch {\r\n try {\r\n const data = await response.blob() as T;\r\n return { data, dataType: \"blob\" };\r\n } catch {\r\n const buffer = await response.arrayBuffer();\r\n const data = new Uint8Array(buffer) as T;\r\n return { data, dataType: \"bytes\" };\r\n }\r\n }\r\n }\r\n}\r\n","import { GaniaCache } from \"./cache/gania-cache\";\r\nimport { getResponseData } from \"./response\";\r\nimport {\r\n BaseUrl,\r\n CreateGaniaOptions,\r\n GaniaDbSchema,\r\n GaniaRequestConfig,\r\n GaniaRequestInit,\r\n GaniaResponse,\r\n} from \"./types\";\r\n\r\nexport default class Gania {\r\n readonly online: boolean;\r\n public baseUrl?: BaseUrl;\r\n /**\r\n * The *`gdb`* is the indexedDB abstracted storage for the Gania data\r\n */\r\n private readonly gdb: GaniaCache<GaniaDbSchema>;\r\n constructor(options?: CreateGaniaOptions) {\r\n this.online = navigator.onLine;\r\n this.gdb = new GaniaCache<GaniaDbSchema>(\"ganiadb\");\r\n this.baseUrl = options?.baseUrl;\r\n }\r\n async request<T = unknown>({\r\n method,\r\n input,\r\n ...init\r\n }: GaniaRequestConfig): Promise<GaniaResponse<T>> {\r\n if (!this.online) {\r\n if (method === \"GET\") {\r\n const cached = await this.gdb.get(\r\n \"responses\",\r\n this.createCacheKey(method, input),\r\n );\r\n\r\n return {\r\n data: cached?.data as T,\r\n } as GaniaResponse<T>;\r\n }\r\n\r\n await this.gdb.set(\"mutations\", this.createCacheKey(method!, input), {\r\n method: method!,\r\n url: String(input),\r\n body: init.body,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return {\r\n queued: true,\r\n } as GaniaResponse<T>;\r\n }\r\n if (typeof input === \"string\") input = `${this.baseUrl || \"\"}${input}`;\r\n else input;\r\n const response = await fetch(input, {\r\n ...init,\r\n method,\r\n });\r\n const { data, dataType } = await getResponseData<T>(\r\n response,\r\n init.dataType ?? \"flexible\",\r\n );\r\n if (method === \"GET\") {\r\n await this.gdb.set(\"responses\", this.createCacheKey(method, input), {\r\n data,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n return {\r\n data,\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n ok: response.ok,\r\n dataType,\r\n };\r\n }\r\n createCacheKey(method: string, input: string | URL | Request): string {\r\n return `${method.trim().toUpperCase()}:${String(input)}`;\r\n }\r\n async get<T = any>(input: (string | Request) | URL, init?: GaniaRequestInit) {\r\n return this.request<T>({ method: \"GET\", input, ...init });\r\n }\r\n async post<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"POST\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async put<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PUT\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async patch<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PATCH\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async delete<T = unknown>(\r\n input: string | URL | Request,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"DELETE\",\r\n ...init,\r\n });\r\n }\r\n}\r\n","import Gania from \"./gania\";\r\nimport { CreateGaniaOptions, GaniaInstance, GaniaRequestConfig } from \"./types\";\r\n\r\nexport function create(options?: CreateGaniaOptions): GaniaInstance {\r\n const context = new Gania(options);\r\n\r\n const instance = Object.assign(\r\n <T = unknown>(config: GaniaRequestConfig) => context.request<T>(config),\r\n\r\n {\r\n request: context.request.bind(context),\r\n get: context.get.bind(context),\r\n post: context.post.bind(context),\r\n put: context.put.bind(context),\r\n patch: context.patch.bind(context),\r\n delete: context.delete.bind(context),\r\n create,\r\n },\r\n ) as GaniaInstance;\r\n\r\n return instance;\r\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/cache/gania-cache.ts","../src/response.ts","../src/gania.ts","../src/create.ts"],"sourcesContent":["import { create } from \"./create\";\r\n\r\nconst gania = create();\r\n\r\nexport default gania\r\n\r\nexport { default as Gania } from \"./gania\";\r\nexport { create };\r\nexport * from \"./types\"\r\n","import { GaniaDbSchema } from \"../types\";\r\n\r\ntype CacheEvent =\r\n | {\r\n type: \"set\";\r\n store: string;\r\n key: IDBValidKey;\r\n value: unknown;\r\n }\r\n | {\r\n type: \"delete\";\r\n store: string;\r\n key: IDBValidKey;\r\n }\r\n | {\r\n type: \"clear\";\r\n store: string;\r\n };\r\n\r\nexport class GaniaCache {\r\n private db: IDBDatabase | null = null;\r\n private readonly storeNames = [\r\n \"responses\",\r\n \"mutations\",\r\n ] as const satisfies (keyof GaniaDbSchema)[];\r\n\r\n private readonly DB_NAME = \"ganiadb\";\r\n private readonly VERSION = 1;\r\n\r\n private readonly ramCache = new Map<\r\n keyof GaniaDbSchema,\r\n Map<unknown, unknown>\r\n >();\r\n\r\n private readonly hydratedStores = new Set<keyof GaniaDbSchema>();\r\n\r\n private readonly activeHydrations = new Map<\r\n keyof GaniaDbSchema,\r\n Promise<void>\r\n >();\r\n\r\n private channel: BroadcastChannel | null = null;\r\n\r\n private readonly ready: Promise<this>;\r\n\r\n constructor() {\r\n this.ready = this.#init();\r\n }\r\n\r\n private getDatabase(): IDBDatabase {\r\n if (!this.db) {\r\n throw new Error(\"GaniaCache has not been initialized.\");\r\n }\r\n\r\n return this.db;\r\n }\r\n\r\n private getStoreMap<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Map<GaniaDbSchema[K][\"key\"], GaniaDbSchema[K][\"value\"]> {\r\n const map = this.ramCache.get(store);\r\n\r\n if (!map) {\r\n throw new Error(`Store \"${String(store)}\" is not initialized.`);\r\n }\r\n\r\n return map as Map<GaniaDbSchema[K][\"key\"], GaniaDbSchema[K][\"value\"]>;\r\n }\r\n\r\n async #init(): Promise<this> {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.DB_NAME, this.VERSION);\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result;\r\n\r\n for (const storeName of this.storeNames) {\r\n if (!db.objectStoreNames.contains(storeName as string)) {\r\n db.createObjectStore(storeName as string);\r\n }\r\n }\r\n };\r\n\r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n\r\n for (const storeName of this.storeNames) {\r\n this.ramCache.set(storeName, new Map());\r\n }\r\n\r\n this.channel = new BroadcastChannel(`gania-cache:${this.DB_NAME}`);\r\n\r\n this.channel.onmessage = (event) => this.handleBroadcast(event.data);\r\n\r\n resolve(this);\r\n };\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n private handleBroadcast(event: CacheEvent) {\r\n const storeMap = this.ramCache.get(event.store as keyof GaniaDbSchema);\r\n\r\n if (!storeMap) return;\r\n\r\n switch (event.type) {\r\n case \"set\":\r\n storeMap.set(event.key, event.value);\r\n break;\r\n\r\n case \"delete\":\r\n storeMap.delete(event.key);\r\n break;\r\n\r\n case \"clear\":\r\n storeMap.clear();\r\n break;\r\n }\r\n }\r\n\r\n private broadcast(event: CacheEvent) {\r\n this.channel?.postMessage(event);\r\n }\r\n private async performHydration<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<void> {\r\n const db = this.getDatabase();\r\n\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const objectStore = tx.objectStore(store as string);\r\n\r\n const [keys, values] = await Promise.all([\r\n new Promise<IDBValidKey[]>((resolve, reject) => {\r\n const req = objectStore.getAllKeys();\r\n\r\n req.onsuccess = () => resolve(req.result as IDBValidKey[]);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n\r\n new Promise<unknown[]>((resolve, reject) => {\r\n const req = objectStore.getAll();\r\n\r\n req.onsuccess = () => resolve(req.result);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n ]);\r\n\r\n const storeMap = this.getStoreMap(store);\r\n\r\n keys.forEach((key, index) => {\r\n storeMap.set(\r\n key as GaniaDbSchema[K][\"key\"],\r\n values[index] as GaniaDbSchema[K][\"value\"],\r\n );\r\n });\r\n\r\n this.hydratedStores.add(store);\r\n }\r\n private async hydrateStore<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<void> {\r\n // Already hydrated\r\n if (this.hydratedStores.has(store)) {\r\n return;\r\n }\r\n\r\n // Hydration currently in progress\r\n const activeHydration = this.activeHydrations.get(store);\r\n\r\n if (activeHydration) {\r\n return activeHydration;\r\n }\r\n\r\n const hydrationPromise = this.performHydration(store);\r\n\r\n this.activeHydrations.set(store, hydrationPromise);\r\n\r\n try {\r\n await hydrationPromise;\r\n } finally {\r\n this.activeHydrations.delete(store);\r\n }\r\n }\r\n\r\n async get<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n key: GaniaDbSchema[K][\"key\"],\r\n ): Promise<GaniaDbSchema[K][\"value\"] | null> {\r\n await this.ready;\r\n const storeMap = this.getStoreMap(store);\r\n\r\n if (storeMap.has(key)) {\r\n return storeMap.get(key) ?? null;\r\n }\r\n\r\n const db = this.getDatabase();\r\n\r\n return new Promise((resolve) => {\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const request = tx.objectStore(store as string).get(key as IDBValidKey);\r\n\r\n request.onsuccess = () => {\r\n const value = request.result ?? null;\r\n\r\n if (value !== null) {\r\n storeMap.set(key, value);\r\n }\r\n\r\n resolve(value as GaniaDbSchema[K][\"value\"] | null);\r\n };\r\n\r\n request.onerror = () => resolve(null);\r\n });\r\n }\r\n\r\n async set<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n key: GaniaDbSchema[K][\"key\"],\r\n value: GaniaDbSchema[K][\"value\"],\r\n ): Promise<void> {\r\n await this.ready;\r\n const storeMap = this.getStoreMap(store);\r\n\r\n storeMap.set(key, value);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .put(value, key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"set\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n value,\r\n });\r\n }\r\n\r\n async delete<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n key: GaniaDbSchema[K][\"key\"],\r\n ): Promise<void> {\r\n await this.ready;\r\n this.getStoreMap(store).delete(key);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .delete(key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"delete\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n });\r\n }\r\n\r\n async clear<K extends keyof GaniaDbSchema>(store: K): Promise<void> {\r\n await this.ready;\r\n this.getStoreMap(store).clear();\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx.objectStore(store as string).clear();\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"clear\",\r\n store: String(store),\r\n });\r\n }\r\n\r\n async keys<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<GaniaDbSchema[K][\"key\"][]> {\r\n await this.ready;\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).keys());\r\n }\r\n\r\n async entries<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<[GaniaDbSchema[K][\"key\"], GaniaDbSchema[K][\"value\"]][]> {\r\n await this.ready;\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).entries());\r\n }\r\n\r\n async destroy() {\r\n this.channel?.close();\r\n this.db?.close();\r\n\r\n this.channel = null;\r\n this.db = null;\r\n }\r\n}\r\n","import { GaniaResponse, ResponseDataType } from \"./types\";\r\n\r\nexport class GaniaError<T = any> extends Error {\r\n response?: GaniaResponse<T>;\r\n\r\n constructor(message: string, response?: GaniaResponse<T>) {\r\n super(message);\r\n this.name = \"GaniaError\";\r\n this.response = response;\r\n }\r\n}\r\n\r\nexport async function getResponseData<T = any>(\r\n response: Response,\r\n dataType: ResponseDataType = \"json\",\r\n): Promise<{ data: T; dataType: ResponseDataType }> {\r\n // Handle explicit types safely without unsafe dynamic property lookups\r\n if (dataType !== \"flexible\") {\r\n let data: any;\r\n if (dataType === \"json\") data = await response.json();\r\n else if (dataType === \"text\") data = await response.text();\r\n else if (dataType === \"blob\") data = await response.blob();\r\n else if (dataType === \"bytes\") {\r\n const buffer = await response.arrayBuffer();\r\n data = new Uint8Array(buffer);\r\n }\r\n return { data, dataType };\r\n }\r\n\r\n // Handle the 'flexible' inferred fallback chain correctly\r\n try {\r\n const data = await response.json();\r\n return { data, dataType: \"json\" };\r\n } catch {\r\n try {\r\n const data = await response.text() as T;\r\n return { data, dataType: \"text\" };\r\n } catch {\r\n try {\r\n const data = await response.blob() as T;\r\n return { data, dataType: \"blob\" };\r\n } catch {\r\n const buffer = await response.arrayBuffer();\r\n const data = new Uint8Array(buffer) as T;\r\n return { data, dataType: \"bytes\" };\r\n }\r\n }\r\n }\r\n}\r\n","import { GaniaCache } from \"./cache/gania-cache\";\r\nimport { getResponseData } from \"./response\";\r\nimport {\r\n BaseUrl,\r\n CreateGaniaOptions,\r\n GaniaRequestConfig,\r\n GaniaRequestInit,\r\n GaniaResponse,\r\n} from \"./types\";\r\n\r\nexport default class Gania {\r\n readonly online: boolean;\r\n public baseUrl?: BaseUrl;\r\n /**\r\n * The *`gdb`* is the indexedDB abstracted storage for the Gania data\r\n */\r\n private readonly gdb: GaniaCache;\r\n constructor(options?: CreateGaniaOptions) {\r\n this.online = navigator.onLine;\r\n this.gdb = new GaniaCache();\r\n this.baseUrl = options?.baseUrl;\r\n }\r\n async request<T = unknown>({\r\n method,\r\n input,\r\n ...init\r\n }: GaniaRequestConfig): Promise<GaniaResponse<T>> {\r\n if (!this.online) {\r\n if (method === \"GET\") {\r\n const cached = await this.gdb.get(\r\n \"responses\",\r\n this.createCacheKey(method, input),\r\n );\r\n\r\n return {\r\n data: cached?.data as T,\r\n } as GaniaResponse<T>;\r\n }\r\n\r\n await this.gdb.set(\"mutations\", this.createCacheKey(method!, input), {\r\n method: method!,\r\n url: String(input),\r\n body: init.body,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return {\r\n queued: true,\r\n } as GaniaResponse<T>;\r\n }\r\n if (typeof input === \"string\") input = `${this.baseUrl || \"\"}${input}`;\r\n else input;\r\n const response = await fetch(input, {\r\n ...init,\r\n method,\r\n });\r\n const { data, dataType } = await getResponseData<T>(\r\n response,\r\n init.dataType ?? \"flexible\",\r\n );\r\n if (method === \"GET\") {\r\n await this.gdb.set(\"responses\", this.createCacheKey(method, input), {\r\n data,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n return {\r\n data,\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n ok: response.ok,\r\n dataType,\r\n };\r\n }\r\n createCacheKey(method: string, input: string | URL | Request): string {\r\n return `${method.trim().toUpperCase()}:${String(input)}`;\r\n }\r\n async get<T = any>(input: (string | Request) | URL, init?: GaniaRequestInit) {\r\n return this.request<T>({ method: \"GET\", input, ...init });\r\n }\r\n async post<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"POST\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async put<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PUT\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async patch<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PATCH\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async delete<T = unknown>(\r\n input: string | URL | Request,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"DELETE\",\r\n ...init,\r\n });\r\n }\r\n}\r\n","import Gania from \"./gania\";\r\nimport { CreateGaniaOptions, GaniaInstance, GaniaRequestConfig } from \"./types\";\r\n\r\nexport function create(options?: CreateGaniaOptions): GaniaInstance {\r\n const context = new Gania(options);\r\n\r\n const instance = Object.assign(\r\n <T = unknown>(config: GaniaRequestConfig) => context.request<T>(config),\r\n\r\n {\r\n request: context.request.bind(context),\r\n get: context.get.bind(context),\r\n post: context.post.bind(context),\r\n put: context.put.bind(context),\r\n patch: context.patch.bind(context),\r\n delete: context.delete.bind(context),\r\n create,\r\n },\r\n ) as GaniaInstance;\r\n\r\n return instance;\r\n}"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,16 +1,20 @@
1
1
  // src/cache/gania-cache.ts
2
2
  var GaniaCache = class {
3
- constructor(dbName, version = 1) {
4
- this.dbName = dbName;
5
- this.version = version;
6
- }
7
- dbName;
8
- version;
9
3
  db = null;
4
+ storeNames = [
5
+ "responses",
6
+ "mutations"
7
+ ];
8
+ DB_NAME = "ganiadb";
9
+ VERSION = 1;
10
10
  ramCache = /* @__PURE__ */ new Map();
11
11
  hydratedStores = /* @__PURE__ */ new Set();
12
12
  activeHydrations = /* @__PURE__ */ new Map();
13
13
  channel = null;
14
+ ready;
15
+ constructor() {
16
+ this.ready = this.#init();
17
+ }
14
18
  getDatabase() {
15
19
  if (!this.db) {
16
20
  throw new Error("GaniaCache has not been initialized.");
@@ -24,12 +28,12 @@ var GaniaCache = class {
24
28
  }
25
29
  return map;
26
30
  }
27
- async init(storeNames) {
31
+ async #init() {
28
32
  return new Promise((resolve, reject) => {
29
- const request = indexedDB.open(this.dbName, this.version);
33
+ const request = indexedDB.open(this.DB_NAME, this.VERSION);
30
34
  request.onupgradeneeded = () => {
31
35
  const db = request.result;
32
- for (const storeName of storeNames) {
36
+ for (const storeName of this.storeNames) {
33
37
  if (!db.objectStoreNames.contains(storeName)) {
34
38
  db.createObjectStore(storeName);
35
39
  }
@@ -37,10 +41,10 @@ var GaniaCache = class {
37
41
  };
38
42
  request.onsuccess = () => {
39
43
  this.db = request.result;
40
- for (const storeName of storeNames) {
44
+ for (const storeName of this.storeNames) {
41
45
  this.ramCache.set(storeName, /* @__PURE__ */ new Map());
42
46
  }
43
- this.channel = new BroadcastChannel(`gania-cache:${this.dbName}`);
47
+ this.channel = new BroadcastChannel(`gania-cache:${this.DB_NAME}`);
44
48
  this.channel.onmessage = (event) => this.handleBroadcast(event.data);
45
49
  resolve(this);
46
50
  };
@@ -107,6 +111,7 @@ var GaniaCache = class {
107
111
  }
108
112
  }
109
113
  async get(store, key) {
114
+ await this.ready;
110
115
  const storeMap = this.getStoreMap(store);
111
116
  if (storeMap.has(key)) {
112
117
  return storeMap.get(key) ?? null;
@@ -126,6 +131,7 @@ var GaniaCache = class {
126
131
  });
127
132
  }
128
133
  async set(store, key, value) {
134
+ await this.ready;
129
135
  const storeMap = this.getStoreMap(store);
130
136
  storeMap.set(key, value);
131
137
  const db = this.getDatabase();
@@ -143,6 +149,7 @@ var GaniaCache = class {
143
149
  });
144
150
  }
145
151
  async delete(store, key) {
152
+ await this.ready;
146
153
  this.getStoreMap(store).delete(key);
147
154
  const db = this.getDatabase();
148
155
  await new Promise((resolve, reject) => {
@@ -158,6 +165,7 @@ var GaniaCache = class {
158
165
  });
159
166
  }
160
167
  async clear(store) {
168
+ await this.ready;
161
169
  this.getStoreMap(store).clear();
162
170
  const db = this.getDatabase();
163
171
  await new Promise((resolve, reject) => {
@@ -172,16 +180,20 @@ var GaniaCache = class {
172
180
  });
173
181
  }
174
182
  async keys(store) {
183
+ await this.ready;
175
184
  await this.hydrateStore(store);
176
185
  return Array.from(this.getStoreMap(store).keys());
177
186
  }
178
187
  async entries(store) {
188
+ await this.ready;
179
189
  await this.hydrateStore(store);
180
190
  return Array.from(this.getStoreMap(store).entries());
181
191
  }
182
- destroy() {
192
+ async destroy() {
183
193
  this.channel?.close();
194
+ this.db?.close();
184
195
  this.channel = null;
196
+ this.db = null;
185
197
  }
186
198
  };
187
199
 
@@ -228,7 +240,7 @@ var Gania = class {
228
240
  gdb;
229
241
  constructor(options) {
230
242
  this.online = navigator.onLine;
231
- this.gdb = new GaniaCache("ganiadb");
243
+ this.gdb = new GaniaCache();
232
244
  this.baseUrl = options?.baseUrl;
233
245
  }
234
246
  async request({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cache/gania-cache.ts","../src/response.ts","../src/gania.ts","../src/create.ts","../src/index.ts"],"sourcesContent":["type CacheEvent =\r\n | {\r\n type: \"set\";\r\n store: string;\r\n key: IDBValidKey;\r\n value: unknown;\r\n }\r\n | {\r\n type: \"delete\";\r\n store: string;\r\n key: IDBValidKey;\r\n }\r\n | {\r\n type: \"clear\";\r\n store: string;\r\n };\r\n\r\ntype StoreDef<K = unknown, V = unknown> = {\r\n key: K;\r\n value: V;\r\n};\r\nexport type CacheSchema<T> = { [K in keyof T]: StoreDef };\r\n\r\nexport class GaniaCache<Schema extends CacheSchema<Schema>> {\r\n private db: IDBDatabase | null = null;\r\n\r\n private readonly ramCache = new Map<keyof Schema, Map<unknown, unknown>>();\r\n\r\n private readonly hydratedStores = new Set<keyof Schema>();\r\n\r\n private readonly activeHydrations = new Map<keyof Schema, Promise<void>>();\r\n\r\n private channel: BroadcastChannel | null = null;\r\n\r\n constructor(\r\n private readonly dbName: string,\r\n private readonly version = 1,\r\n ) {}\r\n\r\n private getDatabase(): IDBDatabase {\r\n if (!this.db) {\r\n throw new Error(\"GaniaCache has not been initialized.\");\r\n }\r\n\r\n return this.db;\r\n }\r\n\r\n private getStoreMap<K extends keyof Schema>(\r\n store: K,\r\n ): Map<Schema[K][\"key\"], Schema[K][\"value\"]> {\r\n const map = this.ramCache.get(store);\r\n\r\n if (!map) {\r\n throw new Error(`Store \"${String(store)}\" is not initialized.`);\r\n }\r\n\r\n return map as Map<Schema[K][\"key\"], Schema[K][\"value\"]>;\r\n }\r\n\r\n async init(storeNames: (keyof Schema & string)[]): Promise<this> {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, this.version);\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result;\r\n\r\n for (const storeName of storeNames) {\r\n if (!db.objectStoreNames.contains(storeName)) {\r\n db.createObjectStore(storeName);\r\n }\r\n }\r\n };\r\n\r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n\r\n for (const storeName of storeNames) {\r\n this.ramCache.set(storeName, new Map());\r\n }\r\n\r\n this.channel = new BroadcastChannel(`gania-cache:${this.dbName}`);\r\n\r\n this.channel.onmessage = (event) => this.handleBroadcast(event.data);\r\n\r\n resolve(this);\r\n };\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n private handleBroadcast(event: CacheEvent) {\r\n const storeMap = this.ramCache.get(event.store as keyof Schema);\r\n\r\n if (!storeMap) return;\r\n\r\n switch (event.type) {\r\n case \"set\":\r\n storeMap.set(event.key, event.value);\r\n break;\r\n\r\n case \"delete\":\r\n storeMap.delete(event.key);\r\n break;\r\n\r\n case \"clear\":\r\n storeMap.clear();\r\n break;\r\n }\r\n }\r\n\r\n private broadcast(event: CacheEvent) {\r\n this.channel?.postMessage(event);\r\n }\r\n private async performHydration<K extends keyof Schema>(\r\n store: K,\r\n ): Promise<void> {\r\n const db = this.getDatabase();\r\n\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const objectStore = tx.objectStore(store as string);\r\n\r\n const [keys, values] = await Promise.all([\r\n new Promise<IDBValidKey[]>((resolve, reject) => {\r\n const req = objectStore.getAllKeys();\r\n\r\n req.onsuccess = () => resolve(req.result as IDBValidKey[]);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n\r\n new Promise<unknown[]>((resolve, reject) => {\r\n const req = objectStore.getAll();\r\n\r\n req.onsuccess = () => resolve(req.result);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n ]);\r\n\r\n const storeMap = this.getStoreMap(store);\r\n\r\n keys.forEach((key, index) => {\r\n storeMap.set(\r\n key as Schema[K][\"key\"],\r\n values[index] as Schema[K][\"value\"],\r\n );\r\n });\r\n\r\n this.hydratedStores.add(store);\r\n }\r\n private async hydrateStore<K extends keyof Schema>(store: K): Promise<void> {\r\n // Already hydrated\r\n if (this.hydratedStores.has(store)) {\r\n return;\r\n }\r\n\r\n // Hydration currently in progress\r\n const activeHydration = this.activeHydrations.get(store);\r\n\r\n if (activeHydration) {\r\n return activeHydration;\r\n }\r\n\r\n const hydrationPromise = this.performHydration(store);\r\n\r\n this.activeHydrations.set(store, hydrationPromise);\r\n\r\n try {\r\n await hydrationPromise;\r\n } finally {\r\n this.activeHydrations.delete(store);\r\n }\r\n }\r\n\r\n async get<K extends keyof Schema>(\r\n store: K,\r\n key: Schema[K][\"key\"],\r\n ): Promise<Schema[K][\"value\"] | null> {\r\n const storeMap = this.getStoreMap(store);\r\n\r\n if (storeMap.has(key)) {\r\n return storeMap.get(key) ?? null;\r\n }\r\n\r\n const db = this.getDatabase();\r\n\r\n return new Promise((resolve) => {\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const request = tx.objectStore(store as string).get(key as IDBValidKey);\r\n\r\n request.onsuccess = () => {\r\n const value = request.result ?? null;\r\n\r\n if (value !== null) {\r\n storeMap.set(key, value);\r\n }\r\n\r\n resolve(value as Schema[K][\"value\"] | null);\r\n };\r\n\r\n request.onerror = () => resolve(null);\r\n });\r\n }\r\n\r\n async set<K extends keyof Schema>(\r\n store: K,\r\n key: Schema[K][\"key\"],\r\n value: Schema[K][\"value\"],\r\n ): Promise<void> {\r\n const storeMap = this.getStoreMap(store);\r\n\r\n storeMap.set(key, value);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .put(value, key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"set\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n value,\r\n });\r\n }\r\n\r\n async delete<K extends keyof Schema>(\r\n store: K,\r\n key: Schema[K][\"key\"],\r\n ): Promise<void> {\r\n this.getStoreMap(store).delete(key);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .delete(key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"delete\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n });\r\n }\r\n\r\n async clear<K extends keyof Schema>(store: K): Promise<void> {\r\n this.getStoreMap(store).clear();\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx.objectStore(store as string).clear();\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"clear\",\r\n store: String(store),\r\n });\r\n }\r\n\r\n async keys<K extends keyof Schema>(store: K): Promise<Schema[K][\"key\"][]> {\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).keys());\r\n }\r\n\r\n async entries<K extends keyof Schema>(\r\n store: K,\r\n ): Promise<[Schema[K][\"key\"], Schema[K][\"value\"]][]> {\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).entries());\r\n }\r\n\r\n destroy() {\r\n this.channel?.close();\r\n this.channel = null;\r\n }\r\n}\r\n","import { GaniaResponse, ResponseDataType } from \"./types\";\r\n\r\nexport class GaniaError<T = any> extends Error {\r\n response?: GaniaResponse<T>;\r\n\r\n constructor(message: string, response?: GaniaResponse<T>) {\r\n super(message);\r\n this.name = \"GaniaError\";\r\n this.response = response;\r\n }\r\n}\r\n\r\nexport async function getResponseData<T = any>(\r\n response: Response,\r\n dataType: ResponseDataType = \"json\",\r\n): Promise<{ data: T; dataType: ResponseDataType }> {\r\n // Handle explicit types safely without unsafe dynamic property lookups\r\n if (dataType !== \"flexible\") {\r\n let data: any;\r\n if (dataType === \"json\") data = await response.json();\r\n else if (dataType === \"text\") data = await response.text();\r\n else if (dataType === \"blob\") data = await response.blob();\r\n else if (dataType === \"bytes\") {\r\n const buffer = await response.arrayBuffer();\r\n data = new Uint8Array(buffer);\r\n }\r\n return { data, dataType };\r\n }\r\n\r\n // Handle the 'flexible' inferred fallback chain correctly\r\n try {\r\n const data = await response.json();\r\n return { data, dataType: \"json\" };\r\n } catch {\r\n try {\r\n const data = await response.text() as T;\r\n return { data, dataType: \"text\" };\r\n } catch {\r\n try {\r\n const data = await response.blob() as T;\r\n return { data, dataType: \"blob\" };\r\n } catch {\r\n const buffer = await response.arrayBuffer();\r\n const data = new Uint8Array(buffer) as T;\r\n return { data, dataType: \"bytes\" };\r\n }\r\n }\r\n }\r\n}\r\n","import { GaniaCache } from \"./cache/gania-cache\";\r\nimport { getResponseData } from \"./response\";\r\nimport {\r\n BaseUrl,\r\n CreateGaniaOptions,\r\n GaniaDbSchema,\r\n GaniaRequestConfig,\r\n GaniaRequestInit,\r\n GaniaResponse,\r\n} from \"./types\";\r\n\r\nexport default class Gania {\r\n readonly online: boolean;\r\n public baseUrl?: BaseUrl;\r\n /**\r\n * The *`gdb`* is the indexedDB abstracted storage for the Gania data\r\n */\r\n private readonly gdb: GaniaCache<GaniaDbSchema>;\r\n constructor(options?: CreateGaniaOptions) {\r\n this.online = navigator.onLine;\r\n this.gdb = new GaniaCache<GaniaDbSchema>(\"ganiadb\");\r\n this.baseUrl = options?.baseUrl;\r\n }\r\n async request<T = unknown>({\r\n method,\r\n input,\r\n ...init\r\n }: GaniaRequestConfig): Promise<GaniaResponse<T>> {\r\n if (!this.online) {\r\n if (method === \"GET\") {\r\n const cached = await this.gdb.get(\r\n \"responses\",\r\n this.createCacheKey(method, input),\r\n );\r\n\r\n return {\r\n data: cached?.data as T,\r\n } as GaniaResponse<T>;\r\n }\r\n\r\n await this.gdb.set(\"mutations\", this.createCacheKey(method!, input), {\r\n method: method!,\r\n url: String(input),\r\n body: init.body,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return {\r\n queued: true,\r\n } as GaniaResponse<T>;\r\n }\r\n if (typeof input === \"string\") input = `${this.baseUrl || \"\"}${input}`;\r\n else input;\r\n const response = await fetch(input, {\r\n ...init,\r\n method,\r\n });\r\n const { data, dataType } = await getResponseData<T>(\r\n response,\r\n init.dataType ?? \"flexible\",\r\n );\r\n if (method === \"GET\") {\r\n await this.gdb.set(\"responses\", this.createCacheKey(method, input), {\r\n data,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n return {\r\n data,\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n ok: response.ok,\r\n dataType,\r\n };\r\n }\r\n createCacheKey(method: string, input: string | URL | Request): string {\r\n return `${method.trim().toUpperCase()}:${String(input)}`;\r\n }\r\n async get<T = any>(input: (string | Request) | URL, init?: GaniaRequestInit) {\r\n return this.request<T>({ method: \"GET\", input, ...init });\r\n }\r\n async post<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"POST\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async put<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PUT\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async patch<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PATCH\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async delete<T = unknown>(\r\n input: string | URL | Request,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"DELETE\",\r\n ...init,\r\n });\r\n }\r\n}\r\n","import Gania from \"./gania\";\r\nimport { CreateGaniaOptions, GaniaInstance, GaniaRequestConfig } from \"./types\";\r\n\r\nexport function create(options?: CreateGaniaOptions): GaniaInstance {\r\n const context = new Gania(options);\r\n\r\n const instance = Object.assign(\r\n <T = unknown>(config: GaniaRequestConfig) => context.request<T>(config),\r\n\r\n {\r\n request: context.request.bind(context),\r\n get: context.get.bind(context),\r\n post: context.post.bind(context),\r\n put: context.put.bind(context),\r\n patch: context.patch.bind(context),\r\n delete: context.delete.bind(context),\r\n create,\r\n },\r\n ) as GaniaInstance;\r\n\r\n return instance;\r\n}","import { create } from \"./create\";\r\n\r\nconst gania = create();\r\n\r\nexport default gania\r\n\r\nexport { default as Gania } from \"./gania\";\r\nexport { create };\r\nexport * from \"./types\"\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cache/gania-cache.ts","../src/response.ts","../src/gania.ts","../src/create.ts","../src/index.ts"],"sourcesContent":["import { GaniaDbSchema } from \"../types\";\r\n\r\ntype CacheEvent =\r\n | {\r\n type: \"set\";\r\n store: string;\r\n key: IDBValidKey;\r\n value: unknown;\r\n }\r\n | {\r\n type: \"delete\";\r\n store: string;\r\n key: IDBValidKey;\r\n }\r\n | {\r\n type: \"clear\";\r\n store: string;\r\n };\r\n\r\nexport class GaniaCache {\r\n private db: IDBDatabase | null = null;\r\n private readonly storeNames = [\r\n \"responses\",\r\n \"mutations\",\r\n ] as const satisfies (keyof GaniaDbSchema)[];\r\n\r\n private readonly DB_NAME = \"ganiadb\";\r\n private readonly VERSION = 1;\r\n\r\n private readonly ramCache = new Map<\r\n keyof GaniaDbSchema,\r\n Map<unknown, unknown>\r\n >();\r\n\r\n private readonly hydratedStores = new Set<keyof GaniaDbSchema>();\r\n\r\n private readonly activeHydrations = new Map<\r\n keyof GaniaDbSchema,\r\n Promise<void>\r\n >();\r\n\r\n private channel: BroadcastChannel | null = null;\r\n\r\n private readonly ready: Promise<this>;\r\n\r\n constructor() {\r\n this.ready = this.#init();\r\n }\r\n\r\n private getDatabase(): IDBDatabase {\r\n if (!this.db) {\r\n throw new Error(\"GaniaCache has not been initialized.\");\r\n }\r\n\r\n return this.db;\r\n }\r\n\r\n private getStoreMap<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Map<GaniaDbSchema[K][\"key\"], GaniaDbSchema[K][\"value\"]> {\r\n const map = this.ramCache.get(store);\r\n\r\n if (!map) {\r\n throw new Error(`Store \"${String(store)}\" is not initialized.`);\r\n }\r\n\r\n return map as Map<GaniaDbSchema[K][\"key\"], GaniaDbSchema[K][\"value\"]>;\r\n }\r\n\r\n async #init(): Promise<this> {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.DB_NAME, this.VERSION);\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result;\r\n\r\n for (const storeName of this.storeNames) {\r\n if (!db.objectStoreNames.contains(storeName as string)) {\r\n db.createObjectStore(storeName as string);\r\n }\r\n }\r\n };\r\n\r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n\r\n for (const storeName of this.storeNames) {\r\n this.ramCache.set(storeName, new Map());\r\n }\r\n\r\n this.channel = new BroadcastChannel(`gania-cache:${this.DB_NAME}`);\r\n\r\n this.channel.onmessage = (event) => this.handleBroadcast(event.data);\r\n\r\n resolve(this);\r\n };\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n private handleBroadcast(event: CacheEvent) {\r\n const storeMap = this.ramCache.get(event.store as keyof GaniaDbSchema);\r\n\r\n if (!storeMap) return;\r\n\r\n switch (event.type) {\r\n case \"set\":\r\n storeMap.set(event.key, event.value);\r\n break;\r\n\r\n case \"delete\":\r\n storeMap.delete(event.key);\r\n break;\r\n\r\n case \"clear\":\r\n storeMap.clear();\r\n break;\r\n }\r\n }\r\n\r\n private broadcast(event: CacheEvent) {\r\n this.channel?.postMessage(event);\r\n }\r\n private async performHydration<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<void> {\r\n const db = this.getDatabase();\r\n\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const objectStore = tx.objectStore(store as string);\r\n\r\n const [keys, values] = await Promise.all([\r\n new Promise<IDBValidKey[]>((resolve, reject) => {\r\n const req = objectStore.getAllKeys();\r\n\r\n req.onsuccess = () => resolve(req.result as IDBValidKey[]);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n\r\n new Promise<unknown[]>((resolve, reject) => {\r\n const req = objectStore.getAll();\r\n\r\n req.onsuccess = () => resolve(req.result);\r\n\r\n req.onerror = () => reject(req.error);\r\n }),\r\n ]);\r\n\r\n const storeMap = this.getStoreMap(store);\r\n\r\n keys.forEach((key, index) => {\r\n storeMap.set(\r\n key as GaniaDbSchema[K][\"key\"],\r\n values[index] as GaniaDbSchema[K][\"value\"],\r\n );\r\n });\r\n\r\n this.hydratedStores.add(store);\r\n }\r\n private async hydrateStore<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<void> {\r\n // Already hydrated\r\n if (this.hydratedStores.has(store)) {\r\n return;\r\n }\r\n\r\n // Hydration currently in progress\r\n const activeHydration = this.activeHydrations.get(store);\r\n\r\n if (activeHydration) {\r\n return activeHydration;\r\n }\r\n\r\n const hydrationPromise = this.performHydration(store);\r\n\r\n this.activeHydrations.set(store, hydrationPromise);\r\n\r\n try {\r\n await hydrationPromise;\r\n } finally {\r\n this.activeHydrations.delete(store);\r\n }\r\n }\r\n\r\n async get<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n key: GaniaDbSchema[K][\"key\"],\r\n ): Promise<GaniaDbSchema[K][\"value\"] | null> {\r\n await this.ready;\r\n const storeMap = this.getStoreMap(store);\r\n\r\n if (storeMap.has(key)) {\r\n return storeMap.get(key) ?? null;\r\n }\r\n\r\n const db = this.getDatabase();\r\n\r\n return new Promise((resolve) => {\r\n const tx = db.transaction(store as string, \"readonly\");\r\n\r\n const request = tx.objectStore(store as string).get(key as IDBValidKey);\r\n\r\n request.onsuccess = () => {\r\n const value = request.result ?? null;\r\n\r\n if (value !== null) {\r\n storeMap.set(key, value);\r\n }\r\n\r\n resolve(value as GaniaDbSchema[K][\"value\"] | null);\r\n };\r\n\r\n request.onerror = () => resolve(null);\r\n });\r\n }\r\n\r\n async set<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n key: GaniaDbSchema[K][\"key\"],\r\n value: GaniaDbSchema[K][\"value\"],\r\n ): Promise<void> {\r\n await this.ready;\r\n const storeMap = this.getStoreMap(store);\r\n\r\n storeMap.set(key, value);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .put(value, key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"set\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n value,\r\n });\r\n }\r\n\r\n async delete<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n key: GaniaDbSchema[K][\"key\"],\r\n ): Promise<void> {\r\n await this.ready;\r\n this.getStoreMap(store).delete(key);\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx\r\n .objectStore(store as string)\r\n .delete(key as IDBValidKey);\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"delete\",\r\n store: String(store),\r\n key: key as IDBValidKey,\r\n });\r\n }\r\n\r\n async clear<K extends keyof GaniaDbSchema>(store: K): Promise<void> {\r\n await this.ready;\r\n this.getStoreMap(store).clear();\r\n\r\n const db = this.getDatabase();\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const tx = db.transaction(store as string, \"readwrite\");\r\n\r\n const request = tx.objectStore(store as string).clear();\r\n\r\n request.onsuccess = () => resolve();\r\n\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n this.broadcast({\r\n type: \"clear\",\r\n store: String(store),\r\n });\r\n }\r\n\r\n async keys<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<GaniaDbSchema[K][\"key\"][]> {\r\n await this.ready;\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).keys());\r\n }\r\n\r\n async entries<K extends keyof GaniaDbSchema>(\r\n store: K,\r\n ): Promise<[GaniaDbSchema[K][\"key\"], GaniaDbSchema[K][\"value\"]][]> {\r\n await this.ready;\r\n await this.hydrateStore(store);\r\n\r\n return Array.from(this.getStoreMap(store).entries());\r\n }\r\n\r\n async destroy() {\r\n this.channel?.close();\r\n this.db?.close();\r\n\r\n this.channel = null;\r\n this.db = null;\r\n }\r\n}\r\n","import { GaniaResponse, ResponseDataType } from \"./types\";\r\n\r\nexport class GaniaError<T = any> extends Error {\r\n response?: GaniaResponse<T>;\r\n\r\n constructor(message: string, response?: GaniaResponse<T>) {\r\n super(message);\r\n this.name = \"GaniaError\";\r\n this.response = response;\r\n }\r\n}\r\n\r\nexport async function getResponseData<T = any>(\r\n response: Response,\r\n dataType: ResponseDataType = \"json\",\r\n): Promise<{ data: T; dataType: ResponseDataType }> {\r\n // Handle explicit types safely without unsafe dynamic property lookups\r\n if (dataType !== \"flexible\") {\r\n let data: any;\r\n if (dataType === \"json\") data = await response.json();\r\n else if (dataType === \"text\") data = await response.text();\r\n else if (dataType === \"blob\") data = await response.blob();\r\n else if (dataType === \"bytes\") {\r\n const buffer = await response.arrayBuffer();\r\n data = new Uint8Array(buffer);\r\n }\r\n return { data, dataType };\r\n }\r\n\r\n // Handle the 'flexible' inferred fallback chain correctly\r\n try {\r\n const data = await response.json();\r\n return { data, dataType: \"json\" };\r\n } catch {\r\n try {\r\n const data = await response.text() as T;\r\n return { data, dataType: \"text\" };\r\n } catch {\r\n try {\r\n const data = await response.blob() as T;\r\n return { data, dataType: \"blob\" };\r\n } catch {\r\n const buffer = await response.arrayBuffer();\r\n const data = new Uint8Array(buffer) as T;\r\n return { data, dataType: \"bytes\" };\r\n }\r\n }\r\n }\r\n}\r\n","import { GaniaCache } from \"./cache/gania-cache\";\r\nimport { getResponseData } from \"./response\";\r\nimport {\r\n BaseUrl,\r\n CreateGaniaOptions,\r\n GaniaRequestConfig,\r\n GaniaRequestInit,\r\n GaniaResponse,\r\n} from \"./types\";\r\n\r\nexport default class Gania {\r\n readonly online: boolean;\r\n public baseUrl?: BaseUrl;\r\n /**\r\n * The *`gdb`* is the indexedDB abstracted storage for the Gania data\r\n */\r\n private readonly gdb: GaniaCache;\r\n constructor(options?: CreateGaniaOptions) {\r\n this.online = navigator.onLine;\r\n this.gdb = new GaniaCache();\r\n this.baseUrl = options?.baseUrl;\r\n }\r\n async request<T = unknown>({\r\n method,\r\n input,\r\n ...init\r\n }: GaniaRequestConfig): Promise<GaniaResponse<T>> {\r\n if (!this.online) {\r\n if (method === \"GET\") {\r\n const cached = await this.gdb.get(\r\n \"responses\",\r\n this.createCacheKey(method, input),\r\n );\r\n\r\n return {\r\n data: cached?.data as T,\r\n } as GaniaResponse<T>;\r\n }\r\n\r\n await this.gdb.set(\"mutations\", this.createCacheKey(method!, input), {\r\n method: method!,\r\n url: String(input),\r\n body: init.body,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return {\r\n queued: true,\r\n } as GaniaResponse<T>;\r\n }\r\n if (typeof input === \"string\") input = `${this.baseUrl || \"\"}${input}`;\r\n else input;\r\n const response = await fetch(input, {\r\n ...init,\r\n method,\r\n });\r\n const { data, dataType } = await getResponseData<T>(\r\n response,\r\n init.dataType ?? \"flexible\",\r\n );\r\n if (method === \"GET\") {\r\n await this.gdb.set(\"responses\", this.createCacheKey(method, input), {\r\n data,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n return {\r\n data,\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n ok: response.ok,\r\n dataType,\r\n };\r\n }\r\n createCacheKey(method: string, input: string | URL | Request): string {\r\n return `${method.trim().toUpperCase()}:${String(input)}`;\r\n }\r\n async get<T = any>(input: (string | Request) | URL, init?: GaniaRequestInit) {\r\n return this.request<T>({ method: \"GET\", input, ...init });\r\n }\r\n async post<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"POST\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async put<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PUT\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async patch<T = unknown>(\r\n input: string | URL | Request,\r\n body?: BodyInit,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"PATCH\",\r\n body,\r\n ...init,\r\n });\r\n }\r\n async delete<T = unknown>(\r\n input: string | URL | Request,\r\n init?: GaniaRequestInit,\r\n ) {\r\n return this.request<T>({\r\n input,\r\n method: \"DELETE\",\r\n ...init,\r\n });\r\n }\r\n}\r\n","import Gania from \"./gania\";\r\nimport { CreateGaniaOptions, GaniaInstance, GaniaRequestConfig } from \"./types\";\r\n\r\nexport function create(options?: CreateGaniaOptions): GaniaInstance {\r\n const context = new Gania(options);\r\n\r\n const instance = Object.assign(\r\n <T = unknown>(config: GaniaRequestConfig) => context.request<T>(config),\r\n\r\n {\r\n request: context.request.bind(context),\r\n get: context.get.bind(context),\r\n post: context.post.bind(context),\r\n put: context.put.bind(context),\r\n patch: context.patch.bind(context),\r\n delete: context.delete.bind(context),\r\n create,\r\n },\r\n ) as GaniaInstance;\r\n\r\n return instance;\r\n}","import { create } from \"./create\";\r\n\r\nconst gania = create();\r\n\r\nexport default gania\r\n\r\nexport { default as Gania } from \"./gania\";\r\nexport { create };\r\nexport * from \"./types\"\r\n"],"mappings":";AAmBO,IAAM,aAAN,MAAiB;AAAA,EACd,KAAyB;AAAA,EAChB,aAAa;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AAAA,EAEiB,UAAU;AAAA,EACV,UAAU;AAAA,EAEV,WAAW,oBAAI,IAG9B;AAAA,EAEe,iBAAiB,oBAAI,IAAyB;AAAA,EAE9C,mBAAmB,oBAAI,IAGtC;AAAA,EAEM,UAAmC;AAAA,EAE1B;AAAA,EAEjB,cAAc;AACZ,SAAK,QAAQ,KAAK,MAAM;AAAA,EAC1B;AAAA,EAEQ,cAA2B;AACjC,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,YACN,OACyD;AACzD,UAAM,MAAM,KAAK,SAAS,IAAI,KAAK;AAEnC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,UAAU,OAAO,KAAK,CAAC,uBAAuB;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAuB;AAC3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,UAAU,UAAU,KAAK,KAAK,SAAS,KAAK,OAAO;AAEzD,cAAQ,kBAAkB,MAAM;AAC9B,cAAM,KAAK,QAAQ;AAEnB,mBAAW,aAAa,KAAK,YAAY;AACvC,cAAI,CAAC,GAAG,iBAAiB,SAAS,SAAmB,GAAG;AACtD,eAAG,kBAAkB,SAAmB;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAEA,cAAQ,YAAY,MAAM;AACxB,aAAK,KAAK,QAAQ;AAElB,mBAAW,aAAa,KAAK,YAAY;AACvC,eAAK,SAAS,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,QACxC;AAEA,aAAK,UAAU,IAAI,iBAAiB,eAAe,KAAK,OAAO,EAAE;AAEjE,aAAK,QAAQ,YAAY,CAAC,UAAU,KAAK,gBAAgB,MAAM,IAAI;AAEnE,gBAAQ,IAAI;AAAA,MACd;AAEA,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA,EAEQ,gBAAgB,OAAmB;AACzC,UAAM,WAAW,KAAK,SAAS,IAAI,MAAM,KAA4B;AAErE,QAAI,CAAC,SAAU;AAEf,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,iBAAS,IAAI,MAAM,KAAK,MAAM,KAAK;AACnC;AAAA,MAEF,KAAK;AACH,iBAAS,OAAO,MAAM,GAAG;AACzB;AAAA,MAEF,KAAK;AACH,iBAAS,MAAM;AACf;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,UAAU,OAAmB;AACnC,SAAK,SAAS,YAAY,KAAK;AAAA,EACjC;AAAA,EACA,MAAc,iBACZ,OACe;AACf,UAAM,KAAK,KAAK,YAAY;AAE5B,UAAM,KAAK,GAAG,YAAY,OAAiB,UAAU;AAErD,UAAM,cAAc,GAAG,YAAY,KAAe;AAElD,UAAM,CAAC,MAAM,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvC,IAAI,QAAuB,CAAC,SAAS,WAAW;AAC9C,cAAM,MAAM,YAAY,WAAW;AAEnC,YAAI,YAAY,MAAM,QAAQ,IAAI,MAAuB;AAEzD,YAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,MAED,IAAI,QAAmB,CAAC,SAAS,WAAW;AAC1C,cAAM,MAAM,YAAY,OAAO;AAE/B,YAAI,YAAY,MAAM,QAAQ,IAAI,MAAM;AAExC,YAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAED,UAAM,WAAW,KAAK,YAAY,KAAK;AAEvC,SAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,eAAS;AAAA,QACP;AAAA,QACA,OAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,SAAK,eAAe,IAAI,KAAK;AAAA,EAC/B;AAAA,EACA,MAAc,aACZ,OACe;AAEf,QAAI,KAAK,eAAe,IAAI,KAAK,GAAG;AAClC;AAAA,IACF;AAGA,UAAM,kBAAkB,KAAK,iBAAiB,IAAI,KAAK;AAEvD,QAAI,iBAAiB;AACnB,aAAO;AAAA,IACT;AAEA,UAAM,mBAAmB,KAAK,iBAAiB,KAAK;AAEpD,SAAK,iBAAiB,IAAI,OAAO,gBAAgB;AAEjD,QAAI;AACF,YAAM;AAAA,IACR,UAAE;AACA,WAAK,iBAAiB,OAAO,KAAK;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAM,IACJ,OACA,KAC2C;AAC3C,UAAM,KAAK;AACX,UAAM,WAAW,KAAK,YAAY,KAAK;AAEvC,QAAI,SAAS,IAAI,GAAG,GAAG;AACrB,aAAO,SAAS,IAAI,GAAG,KAAK;AAAA,IAC9B;AAEA,UAAM,KAAK,KAAK,YAAY;AAE5B,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,KAAK,GAAG,YAAY,OAAiB,UAAU;AAErD,YAAM,UAAU,GAAG,YAAY,KAAe,EAAE,IAAI,GAAkB;AAEtE,cAAQ,YAAY,MAAM;AACxB,cAAM,QAAQ,QAAQ,UAAU;AAEhC,YAAI,UAAU,MAAM;AAClB,mBAAS,IAAI,KAAK,KAAK;AAAA,QACzB;AAEA,gBAAQ,KAAyC;AAAA,MACnD;AAEA,cAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IACJ,OACA,KACA,OACe;AACf,UAAM,KAAK;AACX,UAAM,WAAW,KAAK,YAAY,KAAK;AAEvC,aAAS,IAAI,KAAK,KAAK;AAEvB,UAAM,KAAK,KAAK,YAAY;AAE5B,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,KAAK,GAAG,YAAY,OAAiB,WAAW;AAEtD,YAAM,UAAU,GACb,YAAY,KAAe,EAC3B,IAAI,OAAO,GAAkB;AAEhC,cAAQ,YAAY,MAAM,QAAQ;AAElC,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAED,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,OAAO,OAAO,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OACJ,OACA,KACe;AACf,UAAM,KAAK;AACX,SAAK,YAAY,KAAK,EAAE,OAAO,GAAG;AAElC,UAAM,KAAK,KAAK,YAAY;AAE5B,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,KAAK,GAAG,YAAY,OAAiB,WAAW;AAEtD,YAAM,UAAU,GACb,YAAY,KAAe,EAC3B,OAAO,GAAkB;AAE5B,cAAQ,YAAY,MAAM,QAAQ;AAElC,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAED,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,OAAO,OAAO,KAAK;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqC,OAAyB;AAClE,UAAM,KAAK;AACX,SAAK,YAAY,KAAK,EAAE,MAAM;AAE9B,UAAM,KAAK,KAAK,YAAY;AAE5B,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,KAAK,GAAG,YAAY,OAAiB,WAAW;AAEtD,YAAM,UAAU,GAAG,YAAY,KAAe,EAAE,MAAM;AAEtD,cAAQ,YAAY,MAAM,QAAQ;AAElC,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAED,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,OAAO,OAAO,KAAK;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KACJ,OACoC;AACpC,UAAM,KAAK;AACX,UAAM,KAAK,aAAa,KAAK;AAE7B,WAAO,MAAM,KAAK,KAAK,YAAY,KAAK,EAAE,KAAK,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,QACJ,OACiE;AACjE,UAAM,KAAK;AACX,UAAM,KAAK,aAAa,KAAK;AAE7B,WAAO,MAAM,KAAK,KAAK,YAAY,KAAK,EAAE,QAAQ,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,UAAU;AACd,SAAK,SAAS,MAAM;AACpB,SAAK,IAAI,MAAM;AAEf,SAAK,UAAU;AACf,SAAK,KAAK;AAAA,EACZ;AACF;;;AC3TA,eAAsB,gBACpB,UACA,WAA6B,QACqB;AAElD,MAAI,aAAa,YAAY;AAC3B,QAAI;AACJ,QAAI,aAAa,OAAQ,QAAO,MAAM,SAAS,KAAK;AAAA,aAC3C,aAAa,OAAQ,QAAO,MAAM,SAAS,KAAK;AAAA,aAChD,aAAa,OAAQ,QAAO,MAAM,SAAS,KAAK;AAAA,aAChD,aAAa,SAAS;AAC7B,YAAM,SAAS,MAAM,SAAS,YAAY;AAC1C,aAAO,IAAI,WAAW,MAAM;AAAA,IAC9B;AACA,WAAO,EAAE,MAAM,SAAS;AAAA,EAC1B;AAGA,MAAI;AACF,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,EAAE,MAAM,UAAU,OAAO;AAAA,EAClC,QAAQ;AACN,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,EAAE,MAAM,UAAU,OAAO;AAAA,IAClC,QAAQ;AACN,UAAI;AACF,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAO,EAAE,MAAM,UAAU,OAAO;AAAA,MAClC,QAAQ;AACN,cAAM,SAAS,MAAM,SAAS,YAAY;AAC1C,cAAM,OAAO,IAAI,WAAW,MAAM;AAClC,eAAO,EAAE,MAAM,UAAU,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;;;ACtCA,IAAqB,QAArB,MAA2B;AAAA,EAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAIU;AAAA,EACjB,YAAY,SAA8B;AACxC,SAAK,SAAS,UAAU;AACxB,SAAK,MAAM,IAAI,WAAW;AAC1B,SAAK,UAAU,SAAS;AAAA,EAC1B;AAAA,EACA,MAAM,QAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAAkD;AAChD,QAAI,CAAC,KAAK,QAAQ;AAChB,UAAI,WAAW,OAAO;AACpB,cAAM,SAAS,MAAM,KAAK,IAAI;AAAA,UAC5B;AAAA,UACA,KAAK,eAAe,QAAQ,KAAK;AAAA,QACnC;AAEA,eAAO;AAAA,UACL,MAAM,QAAQ;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,KAAK,IAAI,IAAI,aAAa,KAAK,eAAe,QAAS,KAAK,GAAG;AAAA,QACnE;AAAA,QACA,KAAK,OAAO,KAAK;AAAA,QACjB,MAAM,KAAK;AAAA,QACX,WAAW,KAAK,IAAI;AAAA,MACtB,CAAC;AAED,aAAO;AAAA,QACL,QAAQ;AAAA,MACV;AAAA,IACF;AACA,QAAI,OAAO,UAAU,SAAU,SAAQ,GAAG,KAAK,WAAW,EAAE,GAAG,KAAK;AAAA,QAC/D;AACL,UAAM,WAAW,MAAM,MAAM,OAAO;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AACD,UAAM,EAAE,MAAM,SAAS,IAAI,MAAM;AAAA,MAC/B;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AACA,QAAI,WAAW,OAAO;AACpB,YAAM,KAAK,IAAI,IAAI,aAAa,KAAK,eAAe,QAAQ,KAAK,GAAG;AAAA,QAClE;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,MACtB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,MACrB,SAAS,SAAS;AAAA,MAClB,IAAI,SAAS;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EACA,eAAe,QAAgB,OAAuC;AACpE,WAAO,GAAG,OAAO,KAAK,EAAE,YAAY,CAAC,IAAI,OAAO,KAAK,CAAC;AAAA,EACxD;AAAA,EACA,MAAM,IAAa,OAAiC,MAAyB;AAC3E,WAAO,KAAK,QAAW,EAAE,QAAQ,OAAO,OAAO,GAAG,KAAK,CAAC;AAAA,EAC1D;AAAA,EACA,MAAM,KACJ,OACA,MACA,MACA;AACA,WAAO,KAAK,QAAW;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EACA,MAAM,IACJ,OACA,MACA,MACA;AACA,WAAO,KAAK,QAAW;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EACA,MAAM,MACJ,OACA,MACA,MACA;AACA,WAAO,KAAK,QAAW;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EACA,MAAM,OACJ,OACA,MACA;AACA,WAAO,KAAK,QAAW;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;AC5HO,SAAS,OAAO,SAA6C;AAClE,QAAM,UAAU,IAAI,MAAM,OAAO;AAEjC,QAAM,WAAW,OAAO;AAAA,IACtB,CAAc,WAA+B,QAAQ,QAAW,MAAM;AAAA,IAEtE;AAAA,MACE,SAAS,QAAQ,QAAQ,KAAK,OAAO;AAAA,MACrC,KAAK,QAAQ,IAAI,KAAK,OAAO;AAAA,MAC7B,MAAM,QAAQ,KAAK,KAAK,OAAO;AAAA,MAC/B,KAAK,QAAQ,IAAI,KAAK,OAAO;AAAA,MAC7B,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,MACjC,QAAQ,QAAQ,OAAO,KAAK,OAAO;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ACnBA,IAAM,QAAQ,OAAO;AAErB,IAAO,gBAAQ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nditure/gania",
3
- "version": "0.0.0",
3
+ "version": "0.0.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",