@ribbon-studios/js-utils 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -203,30 +203,151 @@ rfetch.delete = (url, options) => {
203
203
  })(rfetch2.is || (rfetch2.is = {}));
204
204
  })(rfetch || (rfetch = {}));
205
205
  const _RibbonStorage = class _RibbonStorage {
206
- static get(storage, key, defaultValue = null) {
206
+ static get(storage, key, defaultValue) {
207
207
  try {
208
208
  const value = storage.getItem(key);
209
- if (!value) return defaultValue;
209
+ if (!value) return defaultValue ?? null;
210
210
  return JSON.parse(value);
211
211
  } catch {
212
- return defaultValue;
212
+ return defaultValue ?? null;
213
213
  }
214
214
  }
215
215
  static set(storage, key, value) {
216
+ const type = storage === localStorage ? "local" : "session";
216
217
  if (value === void 0 || value === null) {
217
218
  storage.removeItem(key);
219
+ _RibbonStorage.$emit("change", {
220
+ type,
221
+ key,
222
+ value: null
223
+ });
218
224
  } else {
219
225
  storage.setItem(key, JSON.stringify(value));
226
+ _RibbonStorage.$emit("change", {
227
+ type,
228
+ key,
229
+ value
230
+ });
220
231
  }
221
232
  }
233
+ static on(key, listener) {
234
+ const index = _RibbonStorage.$listeners[key].indexOf(listener);
235
+ if (index !== -1) return;
236
+ _RibbonStorage.$listeners[key].push(listener);
237
+ }
238
+ static off(key, listener) {
239
+ const index = _RibbonStorage.$listeners[key].indexOf(listener);
240
+ if (index === -1) return;
241
+ _RibbonStorage.$listeners[key].splice(index, 1);
242
+ }
243
+ /**
244
+ * Here be dragons! This should never be called externally!
245
+ * @private
246
+ */
247
+ static $emit(key, ...args) {
248
+ const [event] = args;
249
+ for (const listener of _RibbonStorage.$listeners[key]) {
250
+ listener.apply(void 0, args);
251
+ }
252
+ switch (event.type) {
253
+ case "local":
254
+ _RibbonStorage.local.$emit(key, ...args);
255
+ break;
256
+ case "session":
257
+ _RibbonStorage.session.$emit(key, ...args);
258
+ break;
259
+ }
260
+ }
261
+ /**
262
+ * Resets RibbonStorage to a fresh state.
263
+ * Clearing out listeners and what not.
264
+ */
265
+ static reset() {
266
+ _RibbonStorage.$listeners = {
267
+ change: []
268
+ };
269
+ _RibbonStorage.local.reset();
270
+ _RibbonStorage.session.reset();
271
+ }
272
+ /**
273
+ * Clears local and session storage.
274
+ */
275
+ static clear() {
276
+ localStorage.clear();
277
+ sessionStorage.clear();
278
+ }
222
279
  };
280
+ _RibbonStorage.$listeners = {
281
+ change: []
282
+ };
283
+ window.addEventListener("storage", (event) => {
284
+ if (event.key === null) return;
285
+ _RibbonStorage.$emit("change", {
286
+ type: event.storageArea === localStorage ? "local" : "session",
287
+ key: event.key,
288
+ value: event.newValue === null ? null : JSON.parse(event.newValue)
289
+ });
290
+ });
223
291
  _RibbonStorage.local = {
292
+ $listeners: {
293
+ change: []
294
+ },
224
295
  get: (key, defaultValue) => _RibbonStorage.get(localStorage, key, defaultValue),
225
- set: (key, value) => _RibbonStorage.set(localStorage, key, value)
296
+ set: (key, value) => _RibbonStorage.set(localStorage, key, value),
297
+ on(key, listener) {
298
+ const index = _RibbonStorage.local.$listeners[key].indexOf(listener);
299
+ if (index !== -1) return;
300
+ _RibbonStorage.local.$listeners[key].push(listener);
301
+ },
302
+ off(key, listener) {
303
+ const index = _RibbonStorage.local.$listeners[key].indexOf(listener);
304
+ if (index === -1) return;
305
+ _RibbonStorage.local.$listeners[key].splice(index, 1);
306
+ },
307
+ reset() {
308
+ _RibbonStorage.local.$listeners = {
309
+ change: []
310
+ };
311
+ },
312
+ $emit(key, ...args) {
313
+ for (const listener of _RibbonStorage.local.$listeners[key]) {
314
+ listener.apply(void 0, args);
315
+ }
316
+ }
226
317
  };
227
318
  _RibbonStorage.session = {
319
+ /**
320
+ * Here be dragons!
321
+ *
322
+ * If you need to remove a listener use {@link RibbonStorage.off}
323
+ * to reset all listeners use {@link RibbonStorage.reset}
324
+ * @private
325
+ */
326
+ $listeners: {
327
+ change: []
328
+ },
228
329
  get: (key, defaultValue) => _RibbonStorage.get(sessionStorage, key, defaultValue),
229
- set: (key, value) => _RibbonStorage.set(sessionStorage, key, value)
330
+ set: (key, value) => _RibbonStorage.set(sessionStorage, key, value),
331
+ on(key, listener) {
332
+ const index = _RibbonStorage.session.$listeners[key].indexOf(listener);
333
+ if (index !== -1) return;
334
+ _RibbonStorage.session.$listeners[key].push(listener);
335
+ },
336
+ off(key, listener) {
337
+ const index = _RibbonStorage.session.$listeners[key].indexOf(listener);
338
+ if (index === -1) return;
339
+ _RibbonStorage.session.$listeners[key].splice(index, 1);
340
+ },
341
+ reset() {
342
+ _RibbonStorage.session.$listeners = {
343
+ change: []
344
+ };
345
+ },
346
+ $emit(key, ...args) {
347
+ for (const listener of _RibbonStorage.session.$listeners[key]) {
348
+ listener.apply(void 0, args);
349
+ }
350
+ }
230
351
  };
231
352
  let RibbonStorage = _RibbonStorage;
232
353
  exports.DelimiterType = DelimiterType;
package/dist/index.js CHANGED
@@ -201,30 +201,151 @@ rfetch.delete = (url, options) => {
201
201
  })(rfetch2.is || (rfetch2.is = {}));
202
202
  })(rfetch || (rfetch = {}));
203
203
  const _RibbonStorage = class _RibbonStorage {
204
- static get(storage, key, defaultValue = null) {
204
+ static get(storage, key, defaultValue) {
205
205
  try {
206
206
  const value = storage.getItem(key);
207
- if (!value) return defaultValue;
207
+ if (!value) return defaultValue ?? null;
208
208
  return JSON.parse(value);
209
209
  } catch {
210
- return defaultValue;
210
+ return defaultValue ?? null;
211
211
  }
212
212
  }
213
213
  static set(storage, key, value) {
214
+ const type = storage === localStorage ? "local" : "session";
214
215
  if (value === void 0 || value === null) {
215
216
  storage.removeItem(key);
217
+ _RibbonStorage.$emit("change", {
218
+ type,
219
+ key,
220
+ value: null
221
+ });
216
222
  } else {
217
223
  storage.setItem(key, JSON.stringify(value));
224
+ _RibbonStorage.$emit("change", {
225
+ type,
226
+ key,
227
+ value
228
+ });
218
229
  }
219
230
  }
231
+ static on(key, listener) {
232
+ const index = _RibbonStorage.$listeners[key].indexOf(listener);
233
+ if (index !== -1) return;
234
+ _RibbonStorage.$listeners[key].push(listener);
235
+ }
236
+ static off(key, listener) {
237
+ const index = _RibbonStorage.$listeners[key].indexOf(listener);
238
+ if (index === -1) return;
239
+ _RibbonStorage.$listeners[key].splice(index, 1);
240
+ }
241
+ /**
242
+ * Here be dragons! This should never be called externally!
243
+ * @private
244
+ */
245
+ static $emit(key, ...args) {
246
+ const [event] = args;
247
+ for (const listener of _RibbonStorage.$listeners[key]) {
248
+ listener.apply(void 0, args);
249
+ }
250
+ switch (event.type) {
251
+ case "local":
252
+ _RibbonStorage.local.$emit(key, ...args);
253
+ break;
254
+ case "session":
255
+ _RibbonStorage.session.$emit(key, ...args);
256
+ break;
257
+ }
258
+ }
259
+ /**
260
+ * Resets RibbonStorage to a fresh state.
261
+ * Clearing out listeners and what not.
262
+ */
263
+ static reset() {
264
+ _RibbonStorage.$listeners = {
265
+ change: []
266
+ };
267
+ _RibbonStorage.local.reset();
268
+ _RibbonStorage.session.reset();
269
+ }
270
+ /**
271
+ * Clears local and session storage.
272
+ */
273
+ static clear() {
274
+ localStorage.clear();
275
+ sessionStorage.clear();
276
+ }
220
277
  };
278
+ _RibbonStorage.$listeners = {
279
+ change: []
280
+ };
281
+ window.addEventListener("storage", (event) => {
282
+ if (event.key === null) return;
283
+ _RibbonStorage.$emit("change", {
284
+ type: event.storageArea === localStorage ? "local" : "session",
285
+ key: event.key,
286
+ value: event.newValue === null ? null : JSON.parse(event.newValue)
287
+ });
288
+ });
221
289
  _RibbonStorage.local = {
290
+ $listeners: {
291
+ change: []
292
+ },
222
293
  get: (key, defaultValue) => _RibbonStorage.get(localStorage, key, defaultValue),
223
- set: (key, value) => _RibbonStorage.set(localStorage, key, value)
294
+ set: (key, value) => _RibbonStorage.set(localStorage, key, value),
295
+ on(key, listener) {
296
+ const index = _RibbonStorage.local.$listeners[key].indexOf(listener);
297
+ if (index !== -1) return;
298
+ _RibbonStorage.local.$listeners[key].push(listener);
299
+ },
300
+ off(key, listener) {
301
+ const index = _RibbonStorage.local.$listeners[key].indexOf(listener);
302
+ if (index === -1) return;
303
+ _RibbonStorage.local.$listeners[key].splice(index, 1);
304
+ },
305
+ reset() {
306
+ _RibbonStorage.local.$listeners = {
307
+ change: []
308
+ };
309
+ },
310
+ $emit(key, ...args) {
311
+ for (const listener of _RibbonStorage.local.$listeners[key]) {
312
+ listener.apply(void 0, args);
313
+ }
314
+ }
224
315
  };
225
316
  _RibbonStorage.session = {
317
+ /**
318
+ * Here be dragons!
319
+ *
320
+ * If you need to remove a listener use {@link RibbonStorage.off}
321
+ * to reset all listeners use {@link RibbonStorage.reset}
322
+ * @private
323
+ */
324
+ $listeners: {
325
+ change: []
326
+ },
226
327
  get: (key, defaultValue) => _RibbonStorage.get(sessionStorage, key, defaultValue),
227
- set: (key, value) => _RibbonStorage.set(sessionStorage, key, value)
328
+ set: (key, value) => _RibbonStorage.set(sessionStorage, key, value),
329
+ on(key, listener) {
330
+ const index = _RibbonStorage.session.$listeners[key].indexOf(listener);
331
+ if (index !== -1) return;
332
+ _RibbonStorage.session.$listeners[key].push(listener);
333
+ },
334
+ off(key, listener) {
335
+ const index = _RibbonStorage.session.$listeners[key].indexOf(listener);
336
+ if (index === -1) return;
337
+ _RibbonStorage.session.$listeners[key].splice(index, 1);
338
+ },
339
+ reset() {
340
+ _RibbonStorage.session.$listeners = {
341
+ change: []
342
+ };
343
+ },
344
+ $emit(key, ...args) {
345
+ for (const listener of _RibbonStorage.session.$listeners[key]) {
346
+ listener.apply(void 0, args);
347
+ }
348
+ }
228
349
  };
229
350
  let RibbonStorage = _RibbonStorage;
230
351
  export {
package/dist/storage.d.ts CHANGED
@@ -1,18 +1,65 @@
1
1
  export declare class RibbonStorage {
2
- static get<T>(storage: globalThis.Storage, key: string, defaultValue?: T): T;
2
+ /**
3
+ * Here be dragons!
4
+ *
5
+ * If you need to remove a listener use {@link RibbonStorage.off}
6
+ * to reset all listeners use {@link RibbonStorage.reset}
7
+ * @private
8
+ */
9
+ static $listeners: RibbonStorage.Listeners;
10
+ static get<T>(storage: globalThis.Storage, key: string, defaultValue: T): T;
11
+ static get<T>(storage: globalThis.Storage, key: string, defaultValue?: T): T | null;
3
12
  static set<T>(storage: globalThis.Storage, key: string, value: T): void;
13
+ static on<K extends keyof RibbonStorage.Listeners>(key: K, listener: RibbonStorage.Listeners[K][number]): void;
14
+ static off<K extends keyof RibbonStorage.Listeners>(key: K, listener: RibbonStorage.Listeners[K][number]): void;
15
+ /**
16
+ * Here be dragons! This should never be called externally!
17
+ * @private
18
+ */
19
+ static $emit<K extends keyof RibbonStorage.Listeners>(key: K, ...args: Parameters<RibbonStorage.Listeners[K][number]>): void;
20
+ /**
21
+ * Resets RibbonStorage to a fresh state.
22
+ * Clearing out listeners and what not.
23
+ */
24
+ static reset(): void;
25
+ /**
26
+ * Clears local and session storage.
27
+ */
28
+ static clear(): void;
4
29
  /**
5
30
  * Shorthands for getting / setting from {@link localStorage}
6
31
  */
7
- static local: {
8
- get: <T>(key: string, defaultValue?: T) => T;
9
- set: <T>(key: string, value: T) => void;
10
- };
32
+ static local: RibbonStorage.SubStorage;
11
33
  /**
12
34
  * Shorthands for getting / setting from {@link sessionStorage}
13
35
  */
14
- static session: {
15
- get: <T>(key: string, defaultValue?: T) => T;
16
- set: <T>(key: string, value: T) => void;
36
+ static session: RibbonStorage.SubStorage;
37
+ }
38
+ export declare namespace RibbonStorage {
39
+ type Listeners = {
40
+ change: ((event: ChangeEvent) => void)[];
41
+ };
42
+ type ChangeEvent = {
43
+ type: 'local' | 'session';
44
+ key: string;
45
+ /**
46
+ * This will always be the _parsed_ value!
47
+ */
48
+ value: any;
49
+ };
50
+ type SubStorage = {
51
+ $listeners: Listeners;
52
+ on<K extends keyof Listeners>(key: K, listener: Listeners[K][number]): void;
53
+ off<K extends keyof Listeners>(key: K, listener: Listeners[K][number]): void;
54
+ get<T>(key: string, defaultValue: T): T;
55
+ get<T>(key: string, defaultValue?: T): T | null;
56
+ get<T>(key: string, defaultValue?: T): T | null;
57
+ set<T>(key: string, value: T): void;
58
+ reset(): void;
59
+ /**
60
+ * Here be dragons! This should never be called externally!
61
+ * @private
62
+ */
63
+ $emit<K extends keyof Listeners>(key: K, ...args: Parameters<Listeners[K][number]>): void;
17
64
  };
18
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ribbon-studios/js-utils",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "Collection of generic javascript utilities curated by the Ribbon Studios Team~",
5
5
  "type": "module",
6
6
  "source": "src/*.ts",