@hybridly/utils 0.0.1-dev.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs ADDED
@@ -0,0 +1,355 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const baseMerge = require('deepmerge');
6
+ const makeDebugger = require('debug');
7
+
8
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
9
+
10
+ const baseMerge__default = /*#__PURE__*/_interopDefaultLegacy(baseMerge);
11
+ const makeDebugger__default = /*#__PURE__*/_interopDefaultLegacy(makeDebugger);
12
+
13
+ function hasFiles(data) {
14
+ if (!data) {
15
+ return false;
16
+ }
17
+ return data instanceof File || data instanceof Blob || data instanceof FileList && data.length > 0 || data instanceof FormData && Array.from(data.values()).some((value) => hasFiles(value)) || typeof data === "object" && data !== null && Object.values(data).some((value) => hasFiles(value));
18
+ }
19
+ function objectToFormData(source, form, parentKey) {
20
+ source ?? (source = {});
21
+ form ?? (form = new FormData());
22
+ if (typeof source !== "object" || Array.isArray(source) || source instanceof Blob || source instanceof Date || source instanceof FormData) {
23
+ throw new TypeError("Source must be an object literal to be converted to a FormData object.");
24
+ }
25
+ for (const key in source) {
26
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
27
+ append(form, composeKey(key, parentKey), source[key]);
28
+ }
29
+ }
30
+ return form;
31
+ }
32
+ function composeKey(key, parentKey) {
33
+ return parentKey ? `${parentKey}[${key}]` : key;
34
+ }
35
+ function append(form, key, value) {
36
+ if (Array.isArray(value)) {
37
+ return Array.from(value.keys()).forEach((index) => append(form, composeKey(index.toString(), key), value[index]));
38
+ } else if (value instanceof Date) {
39
+ return form.append(key, value.toISOString());
40
+ } else if (value instanceof File) {
41
+ return form.append(key, value, value.name);
42
+ } else if (value instanceof Blob) {
43
+ return form.append(key, value);
44
+ } else if (typeof value === "boolean") {
45
+ return form.append(key, value ? "1" : "0");
46
+ } else if (typeof value === "string") {
47
+ return form.append(key, value);
48
+ } else if (typeof value === "number") {
49
+ return form.append(key, `${value}`);
50
+ } else if (value === null || value === void 0) {
51
+ return form.append(key, "");
52
+ }
53
+ objectToFormData(value, form, key);
54
+ }
55
+
56
+ class Modal {
57
+ constructor(html, animationDurationInMs = 200) {
58
+ this.html = html;
59
+ this.animationDurationInMs = animationDurationInMs;
60
+ if (this.initializeDOM() !== false) {
61
+ this.show();
62
+ }
63
+ }
64
+ static fromException(response) {
65
+ if (typeof response === "string" && response.trim() !== "") {
66
+ return new Modal(`<style>${htmlStyle()}</style>${response.toString()}`);
67
+ }
68
+ return new Modal(`
69
+ <style>${style()}</style>
70
+ <div class="h-full text-center flex">
71
+ <div class="m-auto">
72
+ <div class="text-5xl font-thin">Error</div>
73
+ <div class="opacity-30 text-lg font-thin m-1">The received response does not respect the Hybridly protocol.</div>
74
+ <pre class="text-sm opacity-80 max-h-[500px] w-full mx-auto text-left mt-6">${JSON.stringify(response, null, 2)}</pre>
75
+ </div>
76
+ </div>
77
+ `);
78
+ }
79
+ static forPageComponent(component) {
80
+ return new Modal(`
81
+ <style>${style()}</style>
82
+ <div class="h-full text-center flex">
83
+ <div class="m-auto">
84
+ <div class="text-5xl font-thin">Error</div>
85
+ <div class="opacity-30 text-lg font-thin m-1">The specified page component does not exist.</div>
86
+ <div class="m-2 flex justify-center text-xl opacity-30 underline underline-dotted">${component}</div>
87
+ </div>
88
+ </div>
89
+ `);
90
+ }
91
+ initializeDOM() {
92
+ if (!this.html) {
93
+ return false;
94
+ }
95
+ if (document.querySelector('[data-hybridly-overlay="true"]')) {
96
+ return false;
97
+ }
98
+ const main = document.createElement("html");
99
+ main.innerHTML = this.html;
100
+ main.querySelectorAll("a").forEach((a) => a.setAttribute("target", "_top"));
101
+ const overlay = document.createElement("div");
102
+ overlay.dataset.hybridly = "";
103
+ overlay.style.position = "fixed";
104
+ overlay.style.width = "100vw";
105
+ overlay.style.height = "100vh";
106
+ overlay.style.padding = "50px";
107
+ overlay.style.boxSizing = "border-box";
108
+ overlay.style.backgroundColor = "rgba(0, 0, 0, .35)";
109
+ overlay.style.color = "white";
110
+ overlay.style.zIndex = "2147483638";
111
+ overlay.style.overflow = "hidden";
112
+ const iframe = document.createElement("iframe");
113
+ iframe.style.backgroundColor = "#050505";
114
+ iframe.style.width = "100%";
115
+ iframe.style.height = "100%";
116
+ iframe.style.borderRadius = "10px";
117
+ overlay.appendChild(iframe);
118
+ const style2 = document.createElement("style");
119
+ style2.innerHTML = `
120
+ [data-hybridly] {
121
+ opacity: 0;
122
+ overflow: hidden;
123
+ transition: opacity ${this.animationDurationInMs}ms ease-out;
124
+ }
125
+
126
+ [data-hybridly="visible"] {
127
+ opacity: 1;
128
+ }
129
+
130
+ [data-hybridly] iframe {
131
+ box-shadow: 0px 10px 35px 5px rgba(0,0,0,0.2);
132
+ opacity: 0;
133
+ overflow: hidden;
134
+ transform: scale(.85);
135
+ transition: all 100ms ease-out;
136
+ }
137
+
138
+ [data-hybridly="visible"] iframe {
139
+ transform: scale(1);
140
+ opacity: 1;
141
+ }
142
+ `;
143
+ this.main = main;
144
+ this.overlay = overlay;
145
+ this.iframe = iframe;
146
+ this.style = style2;
147
+ }
148
+ show() {
149
+ this.overlay.addEventListener("click", () => this.destroy());
150
+ this.hideOnEscape = (event) => {
151
+ if (event.keyCode === 27) {
152
+ this.destroy();
153
+ }
154
+ };
155
+ document.addEventListener("keydown", this.hideOnEscape);
156
+ document.body.prepend(this.style);
157
+ document.body.prepend(this.overlay);
158
+ this.iframe.contentWindow?.document.open();
159
+ this.iframe.contentWindow?.document.write(this.main.outerHTML);
160
+ this.iframe.contentWindow?.document.close();
161
+ this.overlay.dataset.hybridly = "visible";
162
+ }
163
+ destroy() {
164
+ this.overlay.dataset.hybridly = "";
165
+ setTimeout(() => {
166
+ this.overlay.outerHTML = "";
167
+ this.overlay.remove();
168
+ this.style.remove();
169
+ document.removeEventListener("keydown", this.hideOnEscape);
170
+ }, this.animationDurationInMs);
171
+ }
172
+ }
173
+ function showResponseErrorModal(response) {
174
+ return Modal.fromException(response);
175
+ }
176
+ function showPageComponentErrorModal(response) {
177
+ return Modal.forPageComponent(response);
178
+ }
179
+ function htmlStyle() {
180
+ return `
181
+ html {
182
+ background-color: #050505;
183
+ color: white;
184
+ font-family: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";
185
+ display: flex;
186
+ flex-direction: column;
187
+ height: 100%;
188
+ }
189
+ `;
190
+ }
191
+ function style() {
192
+ return `
193
+ ${htmlStyle()}
194
+ body {
195
+ padding: 5rem 2rem;
196
+ flex-grow: 1;
197
+ }
198
+ .m-1 {
199
+ margin: 0.25rem;
200
+ }
201
+ .m-2 {
202
+ margin: 0.5rem;
203
+ }
204
+ .mt-6 {
205
+ margin-top: 1.5rem;
206
+ }
207
+ .m-auto {
208
+ margin: auto;
209
+ }
210
+ .h-full {
211
+ height: 100%;
212
+ }
213
+ .max-h-[500px] {
214
+ max-height: 500px;
215
+ }
216
+ .w-full {
217
+ width: 100%;
218
+ }
219
+ .flex {
220
+ display: flex;
221
+ }
222
+ .justify-center {
223
+ justify-content: center;
224
+ }
225
+ .text-center {
226
+ text-align: center;
227
+ }
228
+ .text-left {
229
+ text-align: left;
230
+ }
231
+ .text-5xl {
232
+ font-size: 3rem;
233
+ line-height: 1;
234
+ }
235
+ .text-lg {
236
+ font-size: 1.125rem;
237
+ line-height: 1.75rem;
238
+ }
239
+ .text-xl {
240
+ font-size: 1.25rem;
241
+ line-height: 1.75rem;
242
+ }
243
+ .text-sm {
244
+ font-size: 0.875rem;
245
+ line-height: 1.25rem;
246
+ }
247
+ .font-thin {
248
+ font-weight: 100;
249
+ }
250
+ .underline {
251
+ text-decoration-line: underline;
252
+ }
253
+ .underline-dotted {
254
+ text-decoration-style: dotted;
255
+ }
256
+ .opacity-30 {
257
+ opacity: 0.3;
258
+ }
259
+ .opacity-80 {
260
+ opacity: 0.8;
261
+ }
262
+ `;
263
+ }
264
+
265
+ function random(length = 10) {
266
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
267
+ let str = "";
268
+ for (let i = 0; i < length; i++) {
269
+ str += chars.charAt(Math.floor(Math.random() * chars.length));
270
+ }
271
+ return str;
272
+ }
273
+ function match(value2, lookup, ...args) {
274
+ if (value2 in lookup || "default" in lookup) {
275
+ const returnValue = value2 in lookup ? lookup[value2] : lookup.default;
276
+ return typeof returnValue === "function" ? returnValue(...args) : returnValue;
277
+ }
278
+ const handlers = Object.keys(lookup).map((key) => `"${key}"`).join(", ");
279
+ const error = new Error(`Tried to handle "${value2}" but there is no handler defined. Only defined handlers are: ${handlers}.`);
280
+ throw error;
281
+ }
282
+ function debounce(fn, delay) {
283
+ let timeoutID;
284
+ return function(...args) {
285
+ clearTimeout(timeoutID);
286
+ timeoutID = setTimeout(() => fn(args), delay);
287
+ };
288
+ }
289
+ function value(value2) {
290
+ if (typeof value2 === "function") {
291
+ return value2?.();
292
+ }
293
+ return value2;
294
+ }
295
+ function when(condition, data, _default) {
296
+ if (!condition) {
297
+ return _default;
298
+ }
299
+ return data;
300
+ }
301
+ function clone(val) {
302
+ let k, out, tmp;
303
+ if (Array.isArray(val)) {
304
+ out = Array(k = val.length);
305
+ while (k--) {
306
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
307
+ }
308
+ return out;
309
+ }
310
+ if (Object.prototype.toString.call(val) === "[object Object]") {
311
+ out = {};
312
+ for (k in val) {
313
+ if (k === "__proto__") {
314
+ Object.defineProperty(out, k, {
315
+ value: clone(val[k]),
316
+ configurable: true,
317
+ enumerable: true,
318
+ writable: true
319
+ });
320
+ } else {
321
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
322
+ }
323
+ }
324
+ return out;
325
+ }
326
+ return val;
327
+ }
328
+ function merge(x, y) {
329
+ return baseMerge__default(x, y, { arrayMerge: (_, s) => s });
330
+ }
331
+
332
+ const debug = {
333
+ router: makeDebugger__default("hybridly:core:router"),
334
+ history: makeDebugger__default("hybridly:core:history"),
335
+ url: makeDebugger__default("hybridly:core:url"),
336
+ context: makeDebugger__default("hybridly:core:context"),
337
+ external: makeDebugger__default("hybridly:core:external"),
338
+ scroll: makeDebugger__default("hybridly:core:scroll"),
339
+ hook: makeDebugger__default("hybridly:core:hook"),
340
+ plugin: (name, ...args) => makeDebugger__default("hybridly:plugin").extend(name.replace("hybridly:", ""))(args.shift(), ...args),
341
+ adapter: (name, ...args) => makeDebugger__default("hybridly:adapter").extend(name)(args.shift(), ...args)
342
+ };
343
+
344
+ exports.clone = clone;
345
+ exports.debounce = debounce;
346
+ exports.debug = debug;
347
+ exports.hasFiles = hasFiles;
348
+ exports.match = match;
349
+ exports.merge = merge;
350
+ exports.objectToFormData = objectToFormData;
351
+ exports.random = random;
352
+ exports.showPageComponentErrorModal = showPageComponentErrorModal;
353
+ exports.showResponseErrorModal = showResponseErrorModal;
354
+ exports.value = value;
355
+ exports.when = when;
@@ -0,0 +1,54 @@
1
+ import makeDebugger from 'debug';
2
+
3
+ declare type RequestData = Record<string, FormDataConvertible> | FormDataConvertible | FormData;
4
+ declare type FormDataConvertible = {
5
+ [key: string]: FormDataConvertible;
6
+ } | Array<FormDataConvertible> | Blob | File | FormDataEntryValue | Date | boolean | number | null | undefined | string;
7
+ /**
8
+ * Checks if the given object has a file.
9
+ */
10
+ declare function hasFiles(data?: RequestData): boolean;
11
+ /**
12
+ * Converts an object literal to a `FormData` object.
13
+ */
14
+ declare function objectToFormData(source?: RequestData, form?: FormData, parentKey?: string): FormData;
15
+
16
+ declare class Modal {
17
+ private html;
18
+ private animationDurationInMs;
19
+ private main;
20
+ private overlay;
21
+ private iframe;
22
+ private style;
23
+ private hideOnEscape?;
24
+ constructor(html: string, animationDurationInMs?: number);
25
+ static fromException(response: string): Modal;
26
+ static forPageComponent(component: string): Modal;
27
+ initializeDOM(): false | undefined;
28
+ show(): void;
29
+ destroy(): void;
30
+ }
31
+ declare function showResponseErrorModal(response: string): Modal;
32
+ declare function showPageComponentErrorModal(response: string): Modal;
33
+
34
+ declare function random(length?: number): string;
35
+ declare function match<TValue extends string | number = string, TReturnValue = unknown>(value: TValue, lookup: Record<TValue | 'default', TReturnValue | ((...args: any[]) => TReturnValue)>, ...args: any[]): TReturnValue | Promise<TReturnValue>;
36
+ declare function debounce<F extends (...params: any[]) => ReturnType<F>>(fn: F, delay: number): F;
37
+ declare function value<T>(value: T | (() => T)): T;
38
+ declare function when<T, D>(condition: any, data: T, _default?: D): T | D | undefined;
39
+ declare function clone<T>(val: T): T;
40
+ declare function merge<T>(x: Partial<T>, y: Partial<T>): T;
41
+
42
+ declare const debug: {
43
+ router: makeDebugger.Debugger;
44
+ history: makeDebugger.Debugger;
45
+ url: makeDebugger.Debugger;
46
+ context: makeDebugger.Debugger;
47
+ external: makeDebugger.Debugger;
48
+ scroll: makeDebugger.Debugger;
49
+ hook: makeDebugger.Debugger;
50
+ plugin: (name: string, ...args: any[]) => void;
51
+ adapter: (name: string, ...args: any[]) => void;
52
+ };
53
+
54
+ export { FormDataConvertible, RequestData, clone, debounce, debug, hasFiles, match, merge, objectToFormData, random, showPageComponentErrorModal, showResponseErrorModal, value, when };
package/dist/index.mjs ADDED
@@ -0,0 +1,335 @@
1
+ import baseMerge from 'deepmerge';
2
+ import makeDebugger from 'debug';
3
+
4
+ function hasFiles(data) {
5
+ if (!data) {
6
+ return false;
7
+ }
8
+ return data instanceof File || data instanceof Blob || data instanceof FileList && data.length > 0 || data instanceof FormData && Array.from(data.values()).some((value) => hasFiles(value)) || typeof data === "object" && data !== null && Object.values(data).some((value) => hasFiles(value));
9
+ }
10
+ function objectToFormData(source, form, parentKey) {
11
+ source ?? (source = {});
12
+ form ?? (form = new FormData());
13
+ if (typeof source !== "object" || Array.isArray(source) || source instanceof Blob || source instanceof Date || source instanceof FormData) {
14
+ throw new TypeError("Source must be an object literal to be converted to a FormData object.");
15
+ }
16
+ for (const key in source) {
17
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
18
+ append(form, composeKey(key, parentKey), source[key]);
19
+ }
20
+ }
21
+ return form;
22
+ }
23
+ function composeKey(key, parentKey) {
24
+ return parentKey ? `${parentKey}[${key}]` : key;
25
+ }
26
+ function append(form, key, value) {
27
+ if (Array.isArray(value)) {
28
+ return Array.from(value.keys()).forEach((index) => append(form, composeKey(index.toString(), key), value[index]));
29
+ } else if (value instanceof Date) {
30
+ return form.append(key, value.toISOString());
31
+ } else if (value instanceof File) {
32
+ return form.append(key, value, value.name);
33
+ } else if (value instanceof Blob) {
34
+ return form.append(key, value);
35
+ } else if (typeof value === "boolean") {
36
+ return form.append(key, value ? "1" : "0");
37
+ } else if (typeof value === "string") {
38
+ return form.append(key, value);
39
+ } else if (typeof value === "number") {
40
+ return form.append(key, `${value}`);
41
+ } else if (value === null || value === void 0) {
42
+ return form.append(key, "");
43
+ }
44
+ objectToFormData(value, form, key);
45
+ }
46
+
47
+ class Modal {
48
+ constructor(html, animationDurationInMs = 200) {
49
+ this.html = html;
50
+ this.animationDurationInMs = animationDurationInMs;
51
+ if (this.initializeDOM() !== false) {
52
+ this.show();
53
+ }
54
+ }
55
+ static fromException(response) {
56
+ if (typeof response === "string" && response.trim() !== "") {
57
+ return new Modal(`<style>${htmlStyle()}</style>${response.toString()}`);
58
+ }
59
+ return new Modal(`
60
+ <style>${style()}</style>
61
+ <div class="h-full text-center flex">
62
+ <div class="m-auto">
63
+ <div class="text-5xl font-thin">Error</div>
64
+ <div class="opacity-30 text-lg font-thin m-1">The received response does not respect the Hybridly protocol.</div>
65
+ <pre class="text-sm opacity-80 max-h-[500px] w-full mx-auto text-left mt-6">${JSON.stringify(response, null, 2)}</pre>
66
+ </div>
67
+ </div>
68
+ `);
69
+ }
70
+ static forPageComponent(component) {
71
+ return new Modal(`
72
+ <style>${style()}</style>
73
+ <div class="h-full text-center flex">
74
+ <div class="m-auto">
75
+ <div class="text-5xl font-thin">Error</div>
76
+ <div class="opacity-30 text-lg font-thin m-1">The specified page component does not exist.</div>
77
+ <div class="m-2 flex justify-center text-xl opacity-30 underline underline-dotted">${component}</div>
78
+ </div>
79
+ </div>
80
+ `);
81
+ }
82
+ initializeDOM() {
83
+ if (!this.html) {
84
+ return false;
85
+ }
86
+ if (document.querySelector('[data-hybridly-overlay="true"]')) {
87
+ return false;
88
+ }
89
+ const main = document.createElement("html");
90
+ main.innerHTML = this.html;
91
+ main.querySelectorAll("a").forEach((a) => a.setAttribute("target", "_top"));
92
+ const overlay = document.createElement("div");
93
+ overlay.dataset.hybridly = "";
94
+ overlay.style.position = "fixed";
95
+ overlay.style.width = "100vw";
96
+ overlay.style.height = "100vh";
97
+ overlay.style.padding = "50px";
98
+ overlay.style.boxSizing = "border-box";
99
+ overlay.style.backgroundColor = "rgba(0, 0, 0, .35)";
100
+ overlay.style.color = "white";
101
+ overlay.style.zIndex = "2147483638";
102
+ overlay.style.overflow = "hidden";
103
+ const iframe = document.createElement("iframe");
104
+ iframe.style.backgroundColor = "#050505";
105
+ iframe.style.width = "100%";
106
+ iframe.style.height = "100%";
107
+ iframe.style.borderRadius = "10px";
108
+ overlay.appendChild(iframe);
109
+ const style2 = document.createElement("style");
110
+ style2.innerHTML = `
111
+ [data-hybridly] {
112
+ opacity: 0;
113
+ overflow: hidden;
114
+ transition: opacity ${this.animationDurationInMs}ms ease-out;
115
+ }
116
+
117
+ [data-hybridly="visible"] {
118
+ opacity: 1;
119
+ }
120
+
121
+ [data-hybridly] iframe {
122
+ box-shadow: 0px 10px 35px 5px rgba(0,0,0,0.2);
123
+ opacity: 0;
124
+ overflow: hidden;
125
+ transform: scale(.85);
126
+ transition: all 100ms ease-out;
127
+ }
128
+
129
+ [data-hybridly="visible"] iframe {
130
+ transform: scale(1);
131
+ opacity: 1;
132
+ }
133
+ `;
134
+ this.main = main;
135
+ this.overlay = overlay;
136
+ this.iframe = iframe;
137
+ this.style = style2;
138
+ }
139
+ show() {
140
+ this.overlay.addEventListener("click", () => this.destroy());
141
+ this.hideOnEscape = (event) => {
142
+ if (event.keyCode === 27) {
143
+ this.destroy();
144
+ }
145
+ };
146
+ document.addEventListener("keydown", this.hideOnEscape);
147
+ document.body.prepend(this.style);
148
+ document.body.prepend(this.overlay);
149
+ this.iframe.contentWindow?.document.open();
150
+ this.iframe.contentWindow?.document.write(this.main.outerHTML);
151
+ this.iframe.contentWindow?.document.close();
152
+ this.overlay.dataset.hybridly = "visible";
153
+ }
154
+ destroy() {
155
+ this.overlay.dataset.hybridly = "";
156
+ setTimeout(() => {
157
+ this.overlay.outerHTML = "";
158
+ this.overlay.remove();
159
+ this.style.remove();
160
+ document.removeEventListener("keydown", this.hideOnEscape);
161
+ }, this.animationDurationInMs);
162
+ }
163
+ }
164
+ function showResponseErrorModal(response) {
165
+ return Modal.fromException(response);
166
+ }
167
+ function showPageComponentErrorModal(response) {
168
+ return Modal.forPageComponent(response);
169
+ }
170
+ function htmlStyle() {
171
+ return `
172
+ html {
173
+ background-color: #050505;
174
+ color: white;
175
+ font-family: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";
176
+ display: flex;
177
+ flex-direction: column;
178
+ height: 100%;
179
+ }
180
+ `;
181
+ }
182
+ function style() {
183
+ return `
184
+ ${htmlStyle()}
185
+ body {
186
+ padding: 5rem 2rem;
187
+ flex-grow: 1;
188
+ }
189
+ .m-1 {
190
+ margin: 0.25rem;
191
+ }
192
+ .m-2 {
193
+ margin: 0.5rem;
194
+ }
195
+ .mt-6 {
196
+ margin-top: 1.5rem;
197
+ }
198
+ .m-auto {
199
+ margin: auto;
200
+ }
201
+ .h-full {
202
+ height: 100%;
203
+ }
204
+ .max-h-[500px] {
205
+ max-height: 500px;
206
+ }
207
+ .w-full {
208
+ width: 100%;
209
+ }
210
+ .flex {
211
+ display: flex;
212
+ }
213
+ .justify-center {
214
+ justify-content: center;
215
+ }
216
+ .text-center {
217
+ text-align: center;
218
+ }
219
+ .text-left {
220
+ text-align: left;
221
+ }
222
+ .text-5xl {
223
+ font-size: 3rem;
224
+ line-height: 1;
225
+ }
226
+ .text-lg {
227
+ font-size: 1.125rem;
228
+ line-height: 1.75rem;
229
+ }
230
+ .text-xl {
231
+ font-size: 1.25rem;
232
+ line-height: 1.75rem;
233
+ }
234
+ .text-sm {
235
+ font-size: 0.875rem;
236
+ line-height: 1.25rem;
237
+ }
238
+ .font-thin {
239
+ font-weight: 100;
240
+ }
241
+ .underline {
242
+ text-decoration-line: underline;
243
+ }
244
+ .underline-dotted {
245
+ text-decoration-style: dotted;
246
+ }
247
+ .opacity-30 {
248
+ opacity: 0.3;
249
+ }
250
+ .opacity-80 {
251
+ opacity: 0.8;
252
+ }
253
+ `;
254
+ }
255
+
256
+ function random(length = 10) {
257
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
258
+ let str = "";
259
+ for (let i = 0; i < length; i++) {
260
+ str += chars.charAt(Math.floor(Math.random() * chars.length));
261
+ }
262
+ return str;
263
+ }
264
+ function match(value2, lookup, ...args) {
265
+ if (value2 in lookup || "default" in lookup) {
266
+ const returnValue = value2 in lookup ? lookup[value2] : lookup.default;
267
+ return typeof returnValue === "function" ? returnValue(...args) : returnValue;
268
+ }
269
+ const handlers = Object.keys(lookup).map((key) => `"${key}"`).join(", ");
270
+ const error = new Error(`Tried to handle "${value2}" but there is no handler defined. Only defined handlers are: ${handlers}.`);
271
+ throw error;
272
+ }
273
+ function debounce(fn, delay) {
274
+ let timeoutID;
275
+ return function(...args) {
276
+ clearTimeout(timeoutID);
277
+ timeoutID = setTimeout(() => fn(args), delay);
278
+ };
279
+ }
280
+ function value(value2) {
281
+ if (typeof value2 === "function") {
282
+ return value2?.();
283
+ }
284
+ return value2;
285
+ }
286
+ function when(condition, data, _default) {
287
+ if (!condition) {
288
+ return _default;
289
+ }
290
+ return data;
291
+ }
292
+ function clone(val) {
293
+ let k, out, tmp;
294
+ if (Array.isArray(val)) {
295
+ out = Array(k = val.length);
296
+ while (k--) {
297
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
298
+ }
299
+ return out;
300
+ }
301
+ if (Object.prototype.toString.call(val) === "[object Object]") {
302
+ out = {};
303
+ for (k in val) {
304
+ if (k === "__proto__") {
305
+ Object.defineProperty(out, k, {
306
+ value: clone(val[k]),
307
+ configurable: true,
308
+ enumerable: true,
309
+ writable: true
310
+ });
311
+ } else {
312
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
313
+ }
314
+ }
315
+ return out;
316
+ }
317
+ return val;
318
+ }
319
+ function merge(x, y) {
320
+ return baseMerge(x, y, { arrayMerge: (_, s) => s });
321
+ }
322
+
323
+ const debug = {
324
+ router: makeDebugger("hybridly:core:router"),
325
+ history: makeDebugger("hybridly:core:history"),
326
+ url: makeDebugger("hybridly:core:url"),
327
+ context: makeDebugger("hybridly:core:context"),
328
+ external: makeDebugger("hybridly:core:external"),
329
+ scroll: makeDebugger("hybridly:core:scroll"),
330
+ hook: makeDebugger("hybridly:core:hook"),
331
+ plugin: (name, ...args) => makeDebugger("hybridly:plugin").extend(name.replace("hybridly:", ""))(args.shift(), ...args),
332
+ adapter: (name, ...args) => makeDebugger("hybridly:adapter").extend(name)(args.shift(), ...args)
333
+ };
334
+
335
+ export { clone, debounce, debug, hasFiles, match, merge, objectToFormData, random, showPageComponentErrorModal, showResponseErrorModal, value, when };
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@hybridly/utils",
3
+ "version": "0.0.1-dev.2",
4
+ "description": "A solution to develop server-driven, client-rendered applications",
5
+ "keywords": [
6
+ "hybridly",
7
+ "inertiajs"
8
+ ],
9
+ "homepage": "https://github.com/hybridly/hybridly#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/hybridly/hybridly/issues"
12
+ },
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/hybridly/hybridly.git"
17
+ },
18
+ "funding": "https://github.com/sponsors/innocenzi",
19
+ "author": "Enzo Innocenzi <enzo@innocenzi.dev>",
20
+ "sideEffects": false,
21
+ "files": [
22
+ "dist",
23
+ "*.d.ts"
24
+ ],
25
+ "exports": {
26
+ ".": {
27
+ "require": "./dist/index.cjs",
28
+ "import": "./dist/index.mjs",
29
+ "types": "./dist/index.d.ts"
30
+ }
31
+ },
32
+ "main": "dist/index.cjs",
33
+ "module": "dist/index.mjs",
34
+ "types": "dist/index.d.ts",
35
+ "dependencies": {
36
+ "debug": "^4.3.4",
37
+ "deepmerge": "^4.2.2"
38
+ },
39
+ "scripts": {
40
+ "build": "unbuild",
41
+ "stub": "unbuild --stub"
42
+ }
43
+ }