@ztimson/utils 0.28.16 → 0.29.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
@@ -2,6 +2,193 @@
2
2
  typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.utils = {}));
3
3
  })(this, (function(exports2) {
4
4
  "use strict";
5
+ var dist = {};
6
+ var persist = {};
7
+ var hasRequiredPersist;
8
+ function requirePersist() {
9
+ if (hasRequiredPersist) return persist;
10
+ hasRequiredPersist = 1;
11
+ Object.defineProperty(persist, "__esModule", { value: true });
12
+ persist.persist = persist.Persist = void 0;
13
+ class Persist {
14
+ key;
15
+ options;
16
+ /** Backend service to store data, must implement `Storage` interface */
17
+ storage;
18
+ /** Listeners which should be notified on changes */
19
+ watches = {};
20
+ /** Private value field */
21
+ _value;
22
+ /** Current value or default if undefined */
23
+ get value() {
24
+ return this._value !== void 0 ? this._value : this.options?.default;
25
+ }
26
+ /** Set value with proxy object wrapper to sync future changes */
27
+ set value(v) {
28
+ if (v == null || typeof v != "object")
29
+ this._value = v;
30
+ else
31
+ this._value = new Proxy(v, {
32
+ get: (target, p) => {
33
+ const f = typeof target[p] == "function";
34
+ if (!f)
35
+ return target[p];
36
+ return (...args) => {
37
+ const value = target[p](...args);
38
+ this.save();
39
+ return value;
40
+ };
41
+ },
42
+ set: (target, p, newValue) => {
43
+ target[p] = newValue;
44
+ this.save();
45
+ return true;
46
+ }
47
+ });
48
+ this.save();
49
+ }
50
+ /**
51
+ * @param {string} key Primary key value will be stored under
52
+ * @param {PersistOptions<T>} options Configure using {@link PersistOptions}
53
+ */
54
+ constructor(key, options = {}) {
55
+ this.key = key;
56
+ this.options = options;
57
+ this.storage = options.storage || localStorage;
58
+ this.load();
59
+ }
60
+ /** Notify listeners of change */
61
+ notify(value) {
62
+ Object.values(this.watches).forEach((watch) => watch(value));
63
+ }
64
+ /** Delete value from storage */
65
+ clear() {
66
+ this.storage.removeItem(this.key);
67
+ }
68
+ /** Save current value to storage */
69
+ save() {
70
+ if (this._value === void 0)
71
+ this.clear();
72
+ else
73
+ this.storage.setItem(this.key, JSON.stringify(this._value));
74
+ this.notify(this.value);
75
+ }
76
+ /** Load value from storage */
77
+ load() {
78
+ if (this.storage[this.key] != void 0) {
79
+ let value = JSON.parse(this.storage.getItem(this.key));
80
+ if (value != null && typeof value == "object" && this.options.type)
81
+ value.__proto__ = this.options.type.prototype;
82
+ this.value = value;
83
+ } else
84
+ this.value = this.options.default || void 0;
85
+ }
86
+ /**
87
+ * Callback function which is run when there are changes
88
+ *
89
+ * @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
90
+ * @returns {() => void} Function which will unsubscribe the watch/callback when called
91
+ */
92
+ watch(fn2) {
93
+ const index = Object.keys(this.watches).length;
94
+ this.watches[index] = fn2;
95
+ return () => {
96
+ delete this.watches[index];
97
+ };
98
+ }
99
+ /**
100
+ * Return value as JSON string
101
+ *
102
+ * @returns {string} Stringified object as JSON
103
+ */
104
+ toString() {
105
+ return JSON.stringify(this.value);
106
+ }
107
+ /**
108
+ * Return current value
109
+ *
110
+ * @returns {T} Current value
111
+ */
112
+ valueOf() {
113
+ return this.value;
114
+ }
115
+ }
116
+ persist.Persist = Persist;
117
+ function persist$1(options) {
118
+ return (target, prop) => {
119
+ const key = options?.key || `${target.constructor.name}.${prop.toString()}`;
120
+ const wrapper = new Persist(key, options);
121
+ Object.defineProperty(target, prop, {
122
+ get: function() {
123
+ return wrapper.value;
124
+ },
125
+ set: function(v) {
126
+ wrapper.value = v;
127
+ }
128
+ });
129
+ };
130
+ }
131
+ persist.persist = persist$1;
132
+ return persist;
133
+ }
134
+ var memoryStorage = {};
135
+ var hasRequiredMemoryStorage;
136
+ function requireMemoryStorage() {
137
+ if (hasRequiredMemoryStorage) return memoryStorage;
138
+ hasRequiredMemoryStorage = 1;
139
+ Object.defineProperty(memoryStorage, "__esModule", { value: true });
140
+ memoryStorage.MemoryStorage = void 0;
141
+ class MemoryStorage {
142
+ get length() {
143
+ return Object.keys(this).length;
144
+ }
145
+ clear() {
146
+ Object.keys(this).forEach((k) => this.removeItem(k));
147
+ }
148
+ getItem(key) {
149
+ return this[key];
150
+ }
151
+ key(index) {
152
+ return Object.keys(this)[index];
153
+ }
154
+ removeItem(key) {
155
+ delete this[key];
156
+ }
157
+ setItem(key, value) {
158
+ this[key] = value;
159
+ }
160
+ }
161
+ memoryStorage.MemoryStorage = MemoryStorage;
162
+ return memoryStorage;
163
+ }
164
+ var hasRequiredDist;
165
+ function requireDist() {
166
+ if (hasRequiredDist) return dist;
167
+ hasRequiredDist = 1;
168
+ (function(exports$1) {
169
+ var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
170
+ if (k2 === void 0) k2 = k;
171
+ var desc = Object.getOwnPropertyDescriptor(m, k);
172
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
173
+ desc = { enumerable: true, get: function() {
174
+ return m[k];
175
+ } };
176
+ }
177
+ Object.defineProperty(o, k2, desc);
178
+ }) : (function(o, m, k, k2) {
179
+ if (k2 === void 0) k2 = k;
180
+ o[k2] = m[k];
181
+ }));
182
+ var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
183
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
184
+ };
185
+ Object.defineProperty(exports$1, "__esModule", { value: true });
186
+ __exportStar(requirePersist(), exports$1);
187
+ __exportStar(requireMemoryStorage(), exports$1);
188
+ })(dist);
189
+ return dist;
190
+ }
191
+ requireDist();
5
192
  class ArgParser {
6
193
  /**
7
194
  * Create a unix-like argument parser to extract flags from the argument list. Can also create help messages.
@@ -30,6 +217,10 @@
30
217
  `--help ${this.commands.length ? "[COMMAND]" : ""}`
31
218
  ].filter((e) => !!e);
32
219
  }
220
+ name;
221
+ desc;
222
+ argList;
223
+ examples;
33
224
  commands = [];
34
225
  args = [];
35
226
  flags = [];
@@ -493,6 +684,8 @@ ${opts.message || this.desc}`;
493
684
  }
494
685
  });
495
686
  }
687
+ key;
688
+ options;
496
689
  _loading;
497
690
  store = /* @__PURE__ */ new Map();
498
691
  timers = /* @__PURE__ */ new Map();
@@ -1278,6 +1471,8 @@ ${opts.message || this.desc}`;
1278
1471
  };
1279
1472
  });
1280
1473
  }
1474
+ database;
1475
+ version;
1281
1476
  schemaLock = new AsyncLock();
1282
1477
  upgrading = false;
1283
1478
  connection;
@@ -1329,6 +1524,9 @@ ${opts.message || this.desc}`;
1329
1524
  if (!exists) this.database.createTable(this.name);
1330
1525
  });
1331
1526
  }
1527
+ database;
1528
+ name;
1529
+ key;
1332
1530
  async tx(table, fn2, readonly = false) {
1333
1531
  await this.database.waitForUpgrade();
1334
1532
  const db = await this.database.connection;
@@ -1871,6 +2069,7 @@ ${opts.message || this.desc}`;
1871
2069
  super();
1872
2070
  this.namespace = namespace;
1873
2071
  }
2072
+ namespace;
1874
2073
  static LOG_LEVEL = 4;
1875
2074
  format(...text) {
1876
2075
  const now = /* @__PURE__ */ new Date();
@@ -2301,6 +2500,7 @@ ${opts.message || this.desc}`;
2301
2500
  constructor(prefix = "") {
2302
2501
  this.prefix = prefix;
2303
2502
  }
2503
+ prefix;
2304
2504
  listeners = [];
2305
2505
  emit(event, ...args) {
2306
2506
  const parsed = event instanceof PathEvent ? event : new PathEvent(`${this.prefix}/${event}`);
@@ -2813,193 +3013,114 @@ ${err.message || err.toString()}`);
2813
3013
  };
2814
3014
  }
2815
3015
  }
2816
- var dist = {};
2817
- var persist = {};
2818
- var hasRequiredPersist;
2819
- function requirePersist() {
2820
- if (hasRequiredPersist) return persist;
2821
- hasRequiredPersist = 1;
2822
- Object.defineProperty(persist, "__esModule", { value: true });
2823
- persist.persist = persist.Persist = void 0;
2824
- class Persist {
2825
- key;
2826
- options;
2827
- /** Backend service to store data, must implement `Storage` interface */
2828
- storage;
2829
- /** Listeners which should be notified on changes */
2830
- watches = {};
2831
- /** Private value field */
2832
- _value;
2833
- /** Current value or default if undefined */
2834
- get value() {
2835
- return this._value !== void 0 ? this._value : this.options?.default;
2836
- }
2837
- /** Set value with proxy object wrapper to sync future changes */
2838
- set value(v) {
2839
- if (v == null || typeof v != "object")
2840
- this._value = v;
2841
- else
2842
- this._value = new Proxy(v, {
2843
- get: (target, p) => {
2844
- const f = typeof target[p] == "function";
2845
- if (!f)
2846
- return target[p];
2847
- return (...args) => {
2848
- const value = target[p](...args);
2849
- this.save();
2850
- return value;
2851
- };
2852
- },
2853
- set: (target, p, newValue) => {
2854
- target[p] = newValue;
2855
- this.save();
2856
- return true;
2857
- }
2858
- });
2859
- this.save();
2860
- }
2861
- /**
2862
- * @param {string} key Primary key value will be stored under
2863
- * @param {PersistOptions<T>} options Configure using {@link PersistOptions}
2864
- */
2865
- constructor(key, options = {}) {
2866
- this.key = key;
2867
- this.options = options;
2868
- this.storage = options.storage || localStorage;
2869
- this.load();
2870
- }
2871
- /** Notify listeners of change */
2872
- notify(value) {
2873
- Object.values(this.watches).forEach((watch) => watch(value));
2874
- }
2875
- /** Delete value from storage */
2876
- clear() {
2877
- this.storage.removeItem(this.key);
2878
- }
2879
- /** Save current value to storage */
2880
- save() {
2881
- if (this._value === void 0)
2882
- this.clear();
2883
- else
2884
- this.storage.setItem(this.key, JSON.stringify(this._value));
2885
- this.notify(this.value);
2886
- }
2887
- /** Load value from storage */
2888
- load() {
2889
- if (this.storage[this.key] != void 0) {
2890
- let value = JSON.parse(this.storage.getItem(this.key));
2891
- if (value != null && typeof value == "object" && this.options.type)
2892
- value.__proto__ = this.options.type.prototype;
2893
- this.value = value;
2894
- } else
2895
- this.value = this.options.default || void 0;
2896
- }
2897
- /**
2898
- * Callback function which is run when there are changes
2899
- *
2900
- * @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
2901
- * @returns {() => void} Function which will unsubscribe the watch/callback when called
2902
- */
2903
- watch(fn2) {
2904
- const index = Object.keys(this.watches).length;
2905
- this.watches[index] = fn2;
2906
- return () => {
2907
- delete this.watches[index];
2908
- };
2909
- }
2910
- /**
2911
- * Return value as JSON string
2912
- *
2913
- * @returns {string} Stringified object as JSON
2914
- */
2915
- toString() {
2916
- return JSON.stringify(this.value);
2917
- }
2918
- /**
2919
- * Return current value
2920
- *
2921
- * @returns {T} Current value
2922
- */
2923
- valueOf() {
2924
- return this.value;
3016
+ function fromXml(xml) {
3017
+ xml = xml.trim();
3018
+ let pos = 0;
3019
+ function parseNode() {
3020
+ skipWhitespace();
3021
+ if (xml[pos] !== "<") return parseText();
3022
+ pos++;
3023
+ if (xml[pos] === "?") {
3024
+ parseDeclaration();
3025
+ return parseNode();
3026
+ }
3027
+ if (xml[pos] === "!") {
3028
+ parseComment();
3029
+ return parseNode();
3030
+ }
3031
+ const tagName = parseTagName();
3032
+ const attributes = parseAttributes();
3033
+ skipWhitespace();
3034
+ if (xml[pos] === "/" && xml[pos + 1] === ">") {
3035
+ pos += 2;
3036
+ return { tag: tagName, attributes, children: [] };
3037
+ }
3038
+ pos++;
3039
+ const children = [];
3040
+ while (pos < xml.length) {
3041
+ skipWhitespace();
3042
+ if (xml[pos] === "<" && xml[pos + 1] === "/") {
3043
+ pos += 2;
3044
+ parseTagName();
3045
+ skipWhitespace();
3046
+ pos++;
3047
+ break;
3048
+ }
3049
+ const child = parseNode();
3050
+ if (child) children.push(child);
3051
+ }
3052
+ return { tag: tagName, attributes, children };
3053
+ }
3054
+ function parseTagName() {
3055
+ let name = "";
3056
+ while (pos < xml.length && /[a-zA-Z0-9_:-]/.test(xml[pos])) name += xml[pos++];
3057
+ return name;
3058
+ }
3059
+ function parseAttributes() {
3060
+ const attrs = {};
3061
+ while (pos < xml.length) {
3062
+ skipWhitespace();
3063
+ if (xml[pos] === ">" || xml[pos] === "/") break;
3064
+ const name = parseTagName();
3065
+ skipWhitespace();
3066
+ if (xml[pos] === "=") {
3067
+ pos++;
3068
+ skipWhitespace();
3069
+ const quote = xml[pos++];
3070
+ let value = "";
3071
+ while (xml[pos] !== quote) value += xml[pos++];
3072
+ pos++;
3073
+ attrs[name] = escapeXml(value, true);
3074
+ }
2925
3075
  }
3076
+ return attrs;
2926
3077
  }
2927
- persist.Persist = Persist;
2928
- function persist$1(options) {
2929
- return (target, prop) => {
2930
- const key = options?.key || `${target.constructor.name}.${prop.toString()}`;
2931
- const wrapper = new Persist(key, options);
2932
- Object.defineProperty(target, prop, {
2933
- get: function() {
2934
- return wrapper.value;
2935
- },
2936
- set: function(v) {
2937
- wrapper.value = v;
2938
- }
2939
- });
2940
- };
3078
+ function parseText() {
3079
+ let text = "";
3080
+ while (pos < xml.length && xml[pos] !== "<") text += xml[pos++];
3081
+ text = text.trim();
3082
+ return text ? escapeXml(text, true) : null;
2941
3083
  }
2942
- persist.persist = persist$1;
2943
- return persist;
3084
+ function parseDeclaration() {
3085
+ while (xml[pos] !== ">") pos++;
3086
+ pos++;
3087
+ }
3088
+ function parseComment() {
3089
+ while (!(xml[pos] === "-" && xml[pos + 1] === "-" && xml[pos + 2] === ">")) pos++;
3090
+ pos += 3;
3091
+ }
3092
+ function skipWhitespace() {
3093
+ while (pos < xml.length && /\s/.test(xml[pos])) pos++;
3094
+ }
3095
+ return parseNode();
2944
3096
  }
2945
- var memoryStorage = {};
2946
- var hasRequiredMemoryStorage;
2947
- function requireMemoryStorage() {
2948
- if (hasRequiredMemoryStorage) return memoryStorage;
2949
- hasRequiredMemoryStorage = 1;
2950
- Object.defineProperty(memoryStorage, "__esModule", { value: true });
2951
- memoryStorage.MemoryStorage = void 0;
2952
- class MemoryStorage {
2953
- get length() {
2954
- return Object.keys(this).length;
2955
- }
2956
- clear() {
2957
- Object.keys(this).forEach((k) => this.removeItem(k));
2958
- }
2959
- getItem(key) {
2960
- return this[key];
2961
- }
2962
- key(index) {
2963
- return Object.keys(this)[index];
2964
- }
2965
- removeItem(key) {
2966
- delete this[key];
2967
- }
2968
- setItem(key, value) {
2969
- this[key] = value;
2970
- }
3097
+ function toXml(obj, indent = "") {
3098
+ if (typeof obj === "string") return escapeXml(obj);
3099
+ const { tag, attributes = {}, children = [] } = obj;
3100
+ let xml = `${indent}<${tag}`;
3101
+ for (const [key, value] of Object.entries(attributes))
3102
+ xml += ` ${key}="${escapeXml(value)}"`;
3103
+ if (children.length === 0) {
3104
+ xml += " />";
3105
+ return xml;
2971
3106
  }
2972
- memoryStorage.MemoryStorage = MemoryStorage;
2973
- return memoryStorage;
3107
+ xml += ">";
3108
+ const hasComplexChildren = children.some((c) => typeof c === "object");
3109
+ for (const child of children) {
3110
+ if (hasComplexChildren) xml += "\n";
3111
+ xml += toXml(child, hasComplexChildren ? indent + " " : "");
3112
+ }
3113
+ if (hasComplexChildren) xml += `
3114
+ ${indent}`;
3115
+ xml += `</${tag}>`;
3116
+ return xml;
2974
3117
  }
2975
- var hasRequiredDist;
2976
- function requireDist() {
2977
- if (hasRequiredDist) return dist;
2978
- hasRequiredDist = 1;
2979
- (function(exports$1) {
2980
- var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
2981
- if (k2 === void 0) k2 = k;
2982
- var desc = Object.getOwnPropertyDescriptor(m, k);
2983
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
2984
- desc = { enumerable: true, get: function() {
2985
- return m[k];
2986
- } };
2987
- }
2988
- Object.defineProperty(o, k2, desc);
2989
- }) : (function(o, m, k, k2) {
2990
- if (k2 === void 0) k2 = k;
2991
- o[k2] = m[k];
2992
- }));
2993
- var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
2994
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
2995
- };
2996
- Object.defineProperty(exports$1, "__esModule", { value: true });
2997
- __exportStar(requirePersist(), exports$1);
2998
- __exportStar(requireMemoryStorage(), exports$1);
2999
- })(dist);
3000
- return dist;
3118
+ function escapeXml(str, decode = false) {
3119
+ if (decode) {
3120
+ return str.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
3121
+ }
3122
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
3001
3123
  }
3002
- requireDist();
3003
3124
  exports2.ASet = ASet;
3004
3125
  exports2.ArgParser = ArgParser;
3005
3126
  exports2.BadGatewayError = BadGatewayError;
@@ -3067,6 +3188,7 @@ ${err.message || err.toString()}`);
3067
3188
  exports2.encodeQuery = encodeQuery;
3068
3189
  exports2.errorFromCode = errorFromCode;
3069
3190
  exports2.escapeRegex = escapeRegex;
3191
+ exports2.escapeXml = escapeXml;
3070
3192
  exports2.fileBrowser = fileBrowser;
3071
3193
  exports2.fileText = fileText;
3072
3194
  exports2.findByProp = findByProp;
@@ -3081,6 +3203,7 @@ ${err.message || err.toString()}`);
3081
3203
  exports2.formatPhoneNumber = formatPhoneNumber;
3082
3204
  exports2.frac2Dec = frac2Dec;
3083
3205
  exports2.fromCsv = fromCsv;
3206
+ exports2.fromXml = fromXml;
3084
3207
  exports2.gravatar = gravatar;
3085
3208
  exports2.hex2Int = hex2Int;
3086
3209
  exports2.hue2rgb = hue2rgb;
@@ -3121,6 +3244,7 @@ ${err.message || err.toString()}`);
3121
3244
  exports2.timestampFilename = timestampFilename;
3122
3245
  exports2.timezoneOffset = timezoneOffset;
3123
3246
  exports2.toCsv = toCsv;
3247
+ exports2.toXml = toXml;
3124
3248
  exports2.uploadWithProgress = uploadWithProgress;
3125
3249
  exports2.validateEmail = validateEmail;
3126
3250
  exports2.wordSegments = wordSegments;