juxscript 1.1.341 → 1.1.343
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/components/sidebar.d.ts.map +1 -0
- package/dist/components/{blocks/sidebar.js → sidebar.js} +4 -4
- package/dist/components/sidebar.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/blocks/menu.d.ts +0 -62
- package/dist/components/blocks/menu.d.ts.map +0 -1
- package/dist/components/blocks/menu.js +0 -149
- package/dist/components/blocks/menu.js.map +0 -1
- package/dist/components/blocks/sidebar.d.ts.map +0 -1
- package/dist/components/blocks/sidebar.js.map +0 -1
- package/dist/lib/components/blocks/menu.d.ts +0 -40
- package/dist/lib/components/blocks/menu.d.ts.map +0 -1
- package/dist/lib/components/blocks/menu.js +0 -136
- package/dist/lib/components/button.d.ts +0 -33
- package/dist/lib/components/button.d.ts.map +0 -1
- package/dist/lib/components/button.js +0 -107
- package/dist/lib/components/checkbox.d.ts +0 -62
- package/dist/lib/components/checkbox.d.ts.map +0 -1
- package/dist/lib/components/checkbox.js +0 -178
- package/dist/lib/components/container.d.ts +0 -58
- package/dist/lib/components/container.d.ts.map +0 -1
- package/dist/lib/components/container.js +0 -151
- package/dist/lib/components/data.d.ts +0 -58
- package/dist/lib/components/data.d.ts.map +0 -1
- package/dist/lib/components/data.js +0 -130
- package/dist/lib/components/grid.d.ts +0 -58
- package/dist/lib/components/grid.d.ts.map +0 -1
- package/dist/lib/components/grid.js +0 -127
- package/dist/lib/components/include.d.ts +0 -86
- package/dist/lib/components/include.d.ts.map +0 -1
- package/dist/lib/components/include.js +0 -238
- package/dist/lib/components/input.d.ts +0 -58
- package/dist/lib/components/input.d.ts.map +0 -1
- package/dist/lib/components/input.js +0 -161
- package/dist/lib/components/link.d.ts +0 -35
- package/dist/lib/components/link.d.ts.map +0 -1
- package/dist/lib/components/link.js +0 -135
- package/dist/lib/components/list.d.ts +0 -48
- package/dist/lib/components/list.d.ts.map +0 -1
- package/dist/lib/components/list.js +0 -178
- package/dist/lib/components/nav.d.ts +0 -46
- package/dist/lib/components/nav.d.ts.map +0 -1
- package/dist/lib/components/nav.js +0 -189
- package/dist/lib/components/radio.d.ts +0 -40
- package/dist/lib/components/radio.d.ts.map +0 -1
- package/dist/lib/components/radio.js +0 -112
- package/dist/lib/components/select.d.ts +0 -41
- package/dist/lib/components/select.d.ts.map +0 -1
- package/dist/lib/components/select.js +0 -111
- package/dist/lib/components/store.d.ts +0 -78
- package/dist/lib/components/store.d.ts.map +0 -1
- package/dist/lib/components/store.js +0 -248
- package/dist/lib/components/style.d.ts +0 -27
- package/dist/lib/components/style.d.ts.map +0 -1
- package/dist/lib/components/style.js +0 -52
- package/dist/lib/components/table.d.ts +0 -56
- package/dist/lib/components/table.d.ts.map +0 -1
- package/dist/lib/components/table.js +0 -199
- package/dist/lib/components/tabs.d.ts +0 -52
- package/dist/lib/components/tabs.d.ts.map +0 -1
- package/dist/lib/components/tabs.js +0 -206
- package/dist/lib/components/tag.d.ts +0 -41
- package/dist/lib/components/tag.d.ts.map +0 -1
- package/dist/lib/components/tag.js +0 -103
- package/dist/lib/devtools/devtools.d.ts +0 -3
- package/dist/lib/devtools/devtools.d.ts.map +0 -1
- package/dist/lib/devtools/devtools.js +0 -181
- package/dist/lib/index.d.ts +0 -70
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/index.js +0 -65
- package/dist/lib/state/pageState.d.ts +0 -19
- package/dist/lib/state/pageState.d.ts.map +0 -1
- package/dist/lib/state/pageState.js +0 -360
- package/dist/lib/utils/codeHighlight.d.ts +0 -7
- package/dist/lib/utils/codeHighlight.d.ts.map +0 -1
- package/dist/lib/utils/codeHighlight.js +0 -105
- package/dist/lib/utils/codeparser.d.ts +0 -29
- package/dist/lib/utils/codeparser.d.ts.map +0 -1
- package/dist/lib/utils/codeparser.js +0 -384
- package/dist/lib/utils/fetch.d.ts +0 -176
- package/dist/lib/utils/fetch.d.ts.map +0 -1
- package/dist/lib/utils/fetch.js +0 -427
- package/dist/lib/utils/formatId.d.ts +0 -16
- package/dist/lib/utils/formatId.d.ts.map +0 -1
- package/dist/lib/utils/formatId.js +0 -27
- package/dist/lib/utils/idgen.d.ts +0 -2
- package/dist/lib/utils/idgen.d.ts.map +0 -1
- package/dist/lib/utils/idgen.js +0 -4
- package/dist/lib/utils/niceName.d.ts +0 -14
- package/dist/lib/utils/niceName.d.ts.map +0 -1
- package/dist/lib/utils/niceName.js +0 -22
- /package/dist/components/{blocks/sidebar.d.ts → sidebar.d.ts} +0 -0
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import generateId from '../utils/idgen.js';
|
|
2
|
-
import { pageState } from '../state/pageState.js';
|
|
3
|
-
class Data {
|
|
4
|
-
constructor(id, options = {}) {
|
|
5
|
-
this._value = null;
|
|
6
|
-
this._loading = false;
|
|
7
|
-
this._error = null;
|
|
8
|
-
this._onChange = null;
|
|
9
|
-
this.id = id || generateId();
|
|
10
|
-
this.options = { method: 'GET', auto: true, ...options };
|
|
11
|
-
}
|
|
12
|
-
// Fluent API
|
|
13
|
-
url(value) { this.options.url = value; return this; }
|
|
14
|
-
method(value) { this.options.method = value; return this; }
|
|
15
|
-
headers(value) { this.options.headers = value; return this; }
|
|
16
|
-
body(value) { this.options.body = value; return this; }
|
|
17
|
-
transform(fn) { this.options.transform = fn; return this; }
|
|
18
|
-
onChange(fn) {
|
|
19
|
-
this._onChange = fn;
|
|
20
|
-
return this;
|
|
21
|
-
}
|
|
22
|
-
// Getters for pageState integration
|
|
23
|
-
getValue() { return this._value; }
|
|
24
|
-
getLoading() { return this._loading; }
|
|
25
|
-
getError() { return this._error; }
|
|
26
|
-
setValue(val) {
|
|
27
|
-
this._value = val;
|
|
28
|
-
if (this._onChange)
|
|
29
|
-
this._onChange(val);
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Re-fetch the data and notify pageState.
|
|
34
|
-
* Triggers all watchers that depend on this data's value.
|
|
35
|
-
*/
|
|
36
|
-
async refresh() {
|
|
37
|
-
const result = await this.fetch();
|
|
38
|
-
// Notify pageState so watchers re-run
|
|
39
|
-
pageState.__notify(`${this.id}.value`);
|
|
40
|
-
pageState.__notify(`${this.id}.loading`);
|
|
41
|
-
return result;
|
|
42
|
-
}
|
|
43
|
-
async fetch(urlOverride) {
|
|
44
|
-
const fetchUrl = urlOverride || this.options.url;
|
|
45
|
-
if (!fetchUrl) {
|
|
46
|
-
this._error = 'No URL provided';
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
this._loading = true;
|
|
50
|
-
this._error = null;
|
|
51
|
-
// Notify pageState of loading change
|
|
52
|
-
if (pageState.__notify) {
|
|
53
|
-
pageState.__notify(`${this.id}.loading`);
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const fetchOptions = {
|
|
57
|
-
method: this.options.method,
|
|
58
|
-
headers: this.options.headers,
|
|
59
|
-
};
|
|
60
|
-
if (this.options.body && this.options.method !== 'GET') {
|
|
61
|
-
fetchOptions.body = typeof this.options.body === 'string'
|
|
62
|
-
? this.options.body
|
|
63
|
-
: JSON.stringify(this.options.body);
|
|
64
|
-
if (!this.options.headers?.['Content-Type']) {
|
|
65
|
-
fetchOptions.headers = {
|
|
66
|
-
'Content-Type': 'application/json',
|
|
67
|
-
...fetchOptions.headers
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const res = await globalThis.fetch(fetchUrl, fetchOptions);
|
|
72
|
-
if (!res.ok) {
|
|
73
|
-
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
74
|
-
}
|
|
75
|
-
const contentType = res.headers.get('content-type') || '';
|
|
76
|
-
let raw;
|
|
77
|
-
if (contentType.includes('application/json')) {
|
|
78
|
-
raw = await res.json();
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
raw = await res.text();
|
|
82
|
-
}
|
|
83
|
-
this._value = this.options.transform ? this.options.transform(raw) : raw;
|
|
84
|
-
this._loading = false;
|
|
85
|
-
this._error = null;
|
|
86
|
-
if (this._onChange)
|
|
87
|
-
this._onChange(this._value);
|
|
88
|
-
return this._value;
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
this._loading = false;
|
|
92
|
-
this._error = err.message || 'Fetch failed';
|
|
93
|
-
console.error(`❌ jux.data('${this.id}') fetch error:`, err.message);
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a data source that integrates with pageState.
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* // Auto-fetch on creation
|
|
103
|
-
* const api = await jux.data('api', { url: '/api/test' });
|
|
104
|
-
* // pageState['api'].value → { users: [...], posts: [...] }
|
|
105
|
-
*
|
|
106
|
-
* // With transform
|
|
107
|
-
* const users = await jux.data('users', {
|
|
108
|
-
* url: '/api/test',
|
|
109
|
-
* transform: raw => raw.users
|
|
110
|
-
* });
|
|
111
|
-
* // pageState['users'].value → [{ id: 1, name: 'Alice' }, ...]
|
|
112
|
-
*
|
|
113
|
-
* // Manual fetch
|
|
114
|
-
* const manual = jux.data('manual', { url: '/api/test', auto: false });
|
|
115
|
-
* await manual.fetch(); // fetch later
|
|
116
|
-
*
|
|
117
|
-
* // Re-fetch
|
|
118
|
-
* await pageState['api'].refresh();
|
|
119
|
-
*/
|
|
120
|
-
export async function data(id, options = {}) {
|
|
121
|
-
const d = new Data(id, options);
|
|
122
|
-
pageState.__register(d);
|
|
123
|
-
if (options.auto !== false && options.url) {
|
|
124
|
-
await d.fetch();
|
|
125
|
-
// Re-register so pageState picks up the fetched value
|
|
126
|
-
pageState.__register(d);
|
|
127
|
-
}
|
|
128
|
-
return d;
|
|
129
|
-
}
|
|
130
|
-
export { Data };
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
type GridDensity = 'dense' | 'normal' | 'inflated';
|
|
2
|
-
interface GridColumn {
|
|
3
|
-
name: string;
|
|
4
|
-
width?: string;
|
|
5
|
-
}
|
|
6
|
-
interface GridOptions {
|
|
7
|
-
rows?: number;
|
|
8
|
-
cols?: number | GridColumn[];
|
|
9
|
-
density?: GridDensity;
|
|
10
|
-
class?: string;
|
|
11
|
-
style?: string;
|
|
12
|
-
target?: string;
|
|
13
|
-
[key: string]: any;
|
|
14
|
-
}
|
|
15
|
-
declare class Grid {
|
|
16
|
-
id: string;
|
|
17
|
-
opts: GridOptions;
|
|
18
|
-
private _element;
|
|
19
|
-
private _columns;
|
|
20
|
-
constructor(id: string, options?: GridOptions);
|
|
21
|
-
getValue(): string;
|
|
22
|
-
getContent(): string;
|
|
23
|
-
setContent(val: string): this;
|
|
24
|
-
setClass(val: string): this;
|
|
25
|
-
setStyle(val: string): this;
|
|
26
|
-
setInnerHTML(val: string): this;
|
|
27
|
-
getElement(): HTMLElement;
|
|
28
|
-
/** Get a named column cell element */
|
|
29
|
-
getColumn(name: string): HTMLElement | null;
|
|
30
|
-
getColumns(): GridColumn[];
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Create a CSS grid layout container.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* // Simple: 3 equal columns
|
|
37
|
-
* jux.grid('cards', { cols: 3 });
|
|
38
|
-
*
|
|
39
|
-
* // Named columns with custom widths
|
|
40
|
-
* jux.grid('layout', {
|
|
41
|
-
* cols: [
|
|
42
|
-
* { name: 'sidebar', width: '260px' },
|
|
43
|
-
* { name: 'content', width: '3fr' },
|
|
44
|
-
* { name: 'aside', width: '1fr' },
|
|
45
|
-
* ]
|
|
46
|
-
* });
|
|
47
|
-
* // Then target into them:
|
|
48
|
-
* jux.nav('main-nav', { target: 'sidebar' });
|
|
49
|
-
* jux.h1('title', { content: 'Hello', target: 'content' });
|
|
50
|
-
*
|
|
51
|
-
* // Density options
|
|
52
|
-
* jux.grid('tight', { cols: 4, density: 'dense' });
|
|
53
|
-
* jux.grid('spacious', { cols: 2, density: 'inflated' });
|
|
54
|
-
*/
|
|
55
|
-
export declare function grid(id: string, options?: GridOptions): Grid;
|
|
56
|
-
export { Grid, GridOptions, GridColumn, GridDensity };
|
|
57
|
-
export default grid;
|
|
58
|
-
//# sourceMappingURL=grid.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../lib/components/grid.ts"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnD,UAAU,UAAU;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,WAAW;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAQD,cAAM,IAAI;IACN,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,QAAQ,CAAoB;gBAExB,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAoEjD,QAAQ,IAAI,MAAM;IAClB,UAAU,IAAI,MAAM;IAEpB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK3B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK/B,UAAU,IAAI,WAAW;IAEzB,sCAAsC;IACtC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI3C,UAAU,IAAI,UAAU,EAAE;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAIhE;AAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACtD,eAAe,IAAI,CAAC"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import generateId from '../utils/idgen.js';
|
|
2
|
-
import { pageState } from '../state/pageState.js';
|
|
3
|
-
const DENSITY_MAP = {
|
|
4
|
-
dense: { gap: '4px', padding: '4px' },
|
|
5
|
-
normal: { gap: '12px', padding: '12px' },
|
|
6
|
-
inflated: { gap: '24px', padding: '24px' },
|
|
7
|
-
};
|
|
8
|
-
class Grid {
|
|
9
|
-
constructor(id, options = {}) {
|
|
10
|
-
this._columns = [];
|
|
11
|
-
this.id = id || generateId();
|
|
12
|
-
this.opts = {
|
|
13
|
-
cols: 2,
|
|
14
|
-
density: 'normal',
|
|
15
|
-
...options
|
|
16
|
-
};
|
|
17
|
-
this._element = document.createElement('div');
|
|
18
|
-
this._element.id = this.id;
|
|
19
|
-
if (this.opts.class)
|
|
20
|
-
this._element.className = this.opts.class;
|
|
21
|
-
// Resolve columns
|
|
22
|
-
const cols = this.opts.cols;
|
|
23
|
-
let templateCols;
|
|
24
|
-
if (cols && typeof cols === 'object' && Array.isArray(cols)) {
|
|
25
|
-
this._columns = cols.map(c => ({
|
|
26
|
-
name: c.name,
|
|
27
|
-
width: c.width || '1fr'
|
|
28
|
-
}));
|
|
29
|
-
templateCols = this._columns.map(c => c.width).join(' ');
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
const count = typeof cols === 'number' ? cols : 2;
|
|
33
|
-
templateCols = `repeat(${count}, 1fr)`;
|
|
34
|
-
}
|
|
35
|
-
const d = DENSITY_MAP[this.opts.density] || DENSITY_MAP.normal;
|
|
36
|
-
const parts = [
|
|
37
|
-
'display:grid',
|
|
38
|
-
`grid-template-columns:${templateCols}`,
|
|
39
|
-
`gap:${d.gap}`,
|
|
40
|
-
`padding:${d.padding}`,
|
|
41
|
-
];
|
|
42
|
-
if (this.opts.rows) {
|
|
43
|
-
parts.push(`grid-template-rows:repeat(${this.opts.rows}, auto)`);
|
|
44
|
-
}
|
|
45
|
-
if (this.opts.style)
|
|
46
|
-
parts.push(this.opts.style);
|
|
47
|
-
this._element.setAttribute('style', parts.join(';'));
|
|
48
|
-
// Extra attributes
|
|
49
|
-
for (const [key, value] of Object.entries(this.opts)) {
|
|
50
|
-
if (['rows', 'cols', 'density', 'class', 'style', 'target'].includes(key))
|
|
51
|
-
continue;
|
|
52
|
-
this._element.setAttribute(`data-${key}`, String(value));
|
|
53
|
-
}
|
|
54
|
-
// Mount
|
|
55
|
-
const resolvedTarget = this.opts.target;
|
|
56
|
-
const parent = resolvedTarget
|
|
57
|
-
? document.getElementById(resolvedTarget) || document.querySelector(resolvedTarget)
|
|
58
|
-
: document.getElementById('app');
|
|
59
|
-
parent?.appendChild(this._element);
|
|
60
|
-
// Create named column cells if using array cols
|
|
61
|
-
if (this._columns.length > 0) {
|
|
62
|
-
for (const col of this._columns) {
|
|
63
|
-
const cell = document.createElement('div');
|
|
64
|
-
cell.id = col.name;
|
|
65
|
-
cell.setAttribute('data-grid-col', col.name);
|
|
66
|
-
this._element.appendChild(cell);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// ═══════════════════════════════════════════════════════════
|
|
71
|
-
// PAGESTATE INTEGRATION
|
|
72
|
-
// ═══════════════════════════════════════════════════════════
|
|
73
|
-
getValue() { return ''; }
|
|
74
|
-
getContent() { return this._element.textContent ?? ''; }
|
|
75
|
-
setContent(val) {
|
|
76
|
-
this._element.textContent = val;
|
|
77
|
-
return this;
|
|
78
|
-
}
|
|
79
|
-
setClass(val) {
|
|
80
|
-
this._element.className = val;
|
|
81
|
-
return this;
|
|
82
|
-
}
|
|
83
|
-
setStyle(val) {
|
|
84
|
-
this._element.setAttribute('style', val);
|
|
85
|
-
return this;
|
|
86
|
-
}
|
|
87
|
-
setInnerHTML(val) {
|
|
88
|
-
this._element.innerHTML = val;
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
getElement() { return this._element; }
|
|
92
|
-
/** Get a named column cell element */
|
|
93
|
-
getColumn(name) {
|
|
94
|
-
return this._element.querySelector(`[data-grid-col="${name}"]`);
|
|
95
|
-
}
|
|
96
|
-
getColumns() { return [...this._columns]; }
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a CSS grid layout container.
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* // Simple: 3 equal columns
|
|
103
|
-
* jux.grid('cards', { cols: 3 });
|
|
104
|
-
*
|
|
105
|
-
* // Named columns with custom widths
|
|
106
|
-
* jux.grid('layout', {
|
|
107
|
-
* cols: [
|
|
108
|
-
* { name: 'sidebar', width: '260px' },
|
|
109
|
-
* { name: 'content', width: '3fr' },
|
|
110
|
-
* { name: 'aside', width: '1fr' },
|
|
111
|
-
* ]
|
|
112
|
-
* });
|
|
113
|
-
* // Then target into them:
|
|
114
|
-
* jux.nav('main-nav', { target: 'sidebar' });
|
|
115
|
-
* jux.h1('title', { content: 'Hello', target: 'content' });
|
|
116
|
-
*
|
|
117
|
-
* // Density options
|
|
118
|
-
* jux.grid('tight', { cols: 4, density: 'dense' });
|
|
119
|
-
* jux.grid('spacious', { cols: 2, density: 'inflated' });
|
|
120
|
-
*/
|
|
121
|
-
export function grid(id, options = {}) {
|
|
122
|
-
const g = new Grid(id, options);
|
|
123
|
-
pageState.__register(g);
|
|
124
|
-
return g;
|
|
125
|
-
}
|
|
126
|
-
export { Grid };
|
|
127
|
-
export default grid;
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Include - Simplified resource injection for bundled and external resources
|
|
3
|
-
* Supports page-specific scoping and cleanup
|
|
4
|
-
*/
|
|
5
|
-
type ResourceType = 'css' | 'js' | 'module';
|
|
6
|
-
interface IncludeOptions {
|
|
7
|
-
type?: ResourceType;
|
|
8
|
-
target?: string;
|
|
9
|
-
async?: boolean;
|
|
10
|
-
defer?: boolean;
|
|
11
|
-
crossOrigin?: 'anonymous' | 'use-credentials';
|
|
12
|
-
integrity?: string;
|
|
13
|
-
pageScoped?: boolean;
|
|
14
|
-
}
|
|
15
|
-
export declare class Include {
|
|
16
|
-
private url;
|
|
17
|
-
private options;
|
|
18
|
-
private element;
|
|
19
|
-
private pageId;
|
|
20
|
-
constructor(url: string, options?: IncludeOptions);
|
|
21
|
-
css(): this;
|
|
22
|
-
js(): this;
|
|
23
|
-
module(): this;
|
|
24
|
-
async(): this;
|
|
25
|
-
defer(): this;
|
|
26
|
-
/**
|
|
27
|
-
* Inject into specific container instead of <head>
|
|
28
|
-
* Useful for page-specific styles
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* jux.include('/css/page1.css').into('#page1-container');
|
|
32
|
-
*/
|
|
33
|
-
into(selector: string): this;
|
|
34
|
-
/**
|
|
35
|
-
* Mark as page-scoped for automatic cleanup
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* jux.include('/css/dashboard.css').forPage('dashboard');
|
|
39
|
-
* // Later: Include.cleanupPage('dashboard');
|
|
40
|
-
*/
|
|
41
|
-
forPage(pageId: string): this;
|
|
42
|
-
render(): this;
|
|
43
|
-
private createStylesheet;
|
|
44
|
-
private createScript;
|
|
45
|
-
private getContainer;
|
|
46
|
-
private isAlreadyLoaded;
|
|
47
|
-
remove(): this;
|
|
48
|
-
/**
|
|
49
|
-
* Remove all resources for a specific page
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* Include.cleanupPage('dashboard');
|
|
53
|
-
*/
|
|
54
|
-
static cleanupPage(pageId: string): void;
|
|
55
|
-
/**
|
|
56
|
-
* Remove all page-scoped resources
|
|
57
|
-
*/
|
|
58
|
-
static cleanupAll(): void;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Factory function - simplified usage
|
|
62
|
-
*
|
|
63
|
-
* Usage:
|
|
64
|
-
* // Basic (auto-detects from extension)
|
|
65
|
-
* jux.include('/css/styles.css');
|
|
66
|
-
* jux.include('/js/app.js');
|
|
67
|
-
*
|
|
68
|
-
* // Page-specific with cleanup
|
|
69
|
-
* jux.include('/css/dashboard.css').forPage('dashboard');
|
|
70
|
-
* jux.include('/js/dashboard.js').forPage('dashboard');
|
|
71
|
-
*
|
|
72
|
-
* // Later cleanup:
|
|
73
|
-
* Include.cleanupPage('dashboard');
|
|
74
|
-
*
|
|
75
|
-
* // Inject into specific container
|
|
76
|
-
* jux.include('/css/widget.css').into('#widget-container');
|
|
77
|
-
*
|
|
78
|
-
* // External CDN
|
|
79
|
-
* jux.include('https://cdn.tailwindcss.com').js();
|
|
80
|
-
*
|
|
81
|
-
* // Module
|
|
82
|
-
* jux.include('/js/app.mjs').module();
|
|
83
|
-
*/
|
|
84
|
-
export declare function include(url: string, options?: IncludeOptions): Include;
|
|
85
|
-
export {};
|
|
86
|
-
//# sourceMappingURL=include.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"include.d.ts","sourceRoot":"","sources":["../../../lib/components/include.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAC;AAE5C,UAAU,cAAc;IACpB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAKD,qBAAa,OAAO;IAChB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAoBrD,GAAG,IAAI,IAAI;IAKX,EAAE,IAAI,IAAI;IAKV,MAAM,IAAI,IAAI;IAKd,KAAK,IAAI,IAAI;IAKb,KAAK,IAAI,IAAI;IAKb;;;;;;OAMG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK5B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAU7B,MAAM,IAAI,IAAI;IAoDd,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,eAAe;IAKvB,MAAM,IAAI,IAAI;IAYd;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAYxC;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;CAS5B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAItE"}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Include - Simplified resource injection for bundled and external resources
|
|
3
|
-
* Supports page-specific scoping and cleanup
|
|
4
|
-
*/
|
|
5
|
-
// Global registry for page-scoped resources
|
|
6
|
-
const scopedResources = new Map();
|
|
7
|
-
export class Include {
|
|
8
|
-
constructor(url, options = {}) {
|
|
9
|
-
this.element = null;
|
|
10
|
-
this.pageId = null;
|
|
11
|
-
this.url = url;
|
|
12
|
-
this.options = options;
|
|
13
|
-
// Auto-detect type from extension if not provided
|
|
14
|
-
if (!options.type) {
|
|
15
|
-
if (url.endsWith('.css')) {
|
|
16
|
-
this.options.type = 'css';
|
|
17
|
-
}
|
|
18
|
-
else if (url.endsWith('.mjs') || url.endsWith('.module.js')) {
|
|
19
|
-
this.options.type = 'module';
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
this.options.type = 'js';
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/* -------------------------
|
|
27
|
-
* Fluent API
|
|
28
|
-
* ------------------------- */
|
|
29
|
-
css() {
|
|
30
|
-
this.options.type = 'css';
|
|
31
|
-
return this;
|
|
32
|
-
}
|
|
33
|
-
js() {
|
|
34
|
-
this.options.type = 'js';
|
|
35
|
-
return this;
|
|
36
|
-
}
|
|
37
|
-
module() {
|
|
38
|
-
this.options.type = 'module';
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
async() {
|
|
42
|
-
this.options.async = true;
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
defer() {
|
|
46
|
-
this.options.defer = true;
|
|
47
|
-
return this;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Inject into specific container instead of <head>
|
|
51
|
-
* Useful for page-specific styles
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* jux.include('/css/page1.css').into('#page1-container');
|
|
55
|
-
*/
|
|
56
|
-
into(selector) {
|
|
57
|
-
this.options.target = selector;
|
|
58
|
-
return this;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Mark as page-scoped for automatic cleanup
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* jux.include('/css/dashboard.css').forPage('dashboard');
|
|
65
|
-
* // Later: Include.cleanupPage('dashboard');
|
|
66
|
-
*/
|
|
67
|
-
forPage(pageId) {
|
|
68
|
-
this.pageId = pageId;
|
|
69
|
-
this.options.pageScoped = true;
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
/* -------------------------
|
|
73
|
-
* Render
|
|
74
|
-
* ------------------------- */
|
|
75
|
-
render() {
|
|
76
|
-
if (typeof document === 'undefined')
|
|
77
|
-
return this;
|
|
78
|
-
try {
|
|
79
|
-
// Check if already loaded
|
|
80
|
-
if (this.isAlreadyLoaded()) {
|
|
81
|
-
console.log(`⚠️ Resource already loaded: ${this.url}`);
|
|
82
|
-
return this;
|
|
83
|
-
}
|
|
84
|
-
// Create element based on type
|
|
85
|
-
let element;
|
|
86
|
-
switch (this.options.type) {
|
|
87
|
-
case 'css':
|
|
88
|
-
element = this.createStylesheet();
|
|
89
|
-
break;
|
|
90
|
-
case 'js':
|
|
91
|
-
case 'module':
|
|
92
|
-
element = this.createScript();
|
|
93
|
-
break;
|
|
94
|
-
default:
|
|
95
|
-
throw new Error(`Unknown resource type: ${this.options.type}`);
|
|
96
|
-
}
|
|
97
|
-
// Get target container
|
|
98
|
-
const container = this.getContainer();
|
|
99
|
-
container.appendChild(element);
|
|
100
|
-
this.element = element;
|
|
101
|
-
// Register for page cleanup if needed
|
|
102
|
-
if (this.options.pageScoped && this.pageId) {
|
|
103
|
-
if (!scopedResources.has(this.pageId)) {
|
|
104
|
-
scopedResources.set(this.pageId, new Set());
|
|
105
|
-
}
|
|
106
|
-
scopedResources.get(this.pageId).add(element);
|
|
107
|
-
}
|
|
108
|
-
console.log(`✓ Loaded ${this.options.type}: ${this.url}`);
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
console.error(`✗ Failed to load ${this.options.type}: ${this.url}`, error);
|
|
112
|
-
throw error;
|
|
113
|
-
}
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
/* -------------------------
|
|
117
|
-
* Element Creation
|
|
118
|
-
* ------------------------- */
|
|
119
|
-
createStylesheet() {
|
|
120
|
-
const link = document.createElement('link');
|
|
121
|
-
link.rel = 'stylesheet';
|
|
122
|
-
link.href = this.url;
|
|
123
|
-
link.dataset.juxInclude = this.url;
|
|
124
|
-
if (this.options.crossOrigin)
|
|
125
|
-
link.crossOrigin = this.options.crossOrigin;
|
|
126
|
-
if (this.options.integrity)
|
|
127
|
-
link.integrity = this.options.integrity;
|
|
128
|
-
link.onload = () => console.log(`✓ Stylesheet loaded: ${this.url}`);
|
|
129
|
-
link.onerror = () => {
|
|
130
|
-
throw new Error(`Failed to load stylesheet: ${this.url}`);
|
|
131
|
-
};
|
|
132
|
-
return link;
|
|
133
|
-
}
|
|
134
|
-
createScript() {
|
|
135
|
-
const script = document.createElement('script');
|
|
136
|
-
script.src = this.url;
|
|
137
|
-
script.dataset.juxInclude = this.url;
|
|
138
|
-
if (this.options.type === 'module')
|
|
139
|
-
script.type = 'module';
|
|
140
|
-
if (this.options.async)
|
|
141
|
-
script.async = true;
|
|
142
|
-
if (this.options.defer)
|
|
143
|
-
script.defer = true;
|
|
144
|
-
if (this.options.crossOrigin)
|
|
145
|
-
script.crossOrigin = this.options.crossOrigin;
|
|
146
|
-
if (this.options.integrity)
|
|
147
|
-
script.integrity = this.options.integrity;
|
|
148
|
-
script.onload = () => console.log(`✓ Script loaded: ${this.url}`);
|
|
149
|
-
script.onerror = () => {
|
|
150
|
-
throw new Error(`Failed to load script: ${this.url}`);
|
|
151
|
-
};
|
|
152
|
-
return script;
|
|
153
|
-
}
|
|
154
|
-
/* -------------------------
|
|
155
|
-
* Helpers
|
|
156
|
-
* ------------------------- */
|
|
157
|
-
getContainer() {
|
|
158
|
-
if (this.options.target) {
|
|
159
|
-
const container = document.querySelector(this.options.target);
|
|
160
|
-
if (!container) {
|
|
161
|
-
throw new Error(`Target container not found: ${this.options.target}`);
|
|
162
|
-
}
|
|
163
|
-
return container;
|
|
164
|
-
}
|
|
165
|
-
return document.head;
|
|
166
|
-
}
|
|
167
|
-
isAlreadyLoaded() {
|
|
168
|
-
const selector = `[data-jux-include="${this.url}"]`;
|
|
169
|
-
return document.querySelector(selector) !== null;
|
|
170
|
-
}
|
|
171
|
-
remove() {
|
|
172
|
-
if (this.element?.parentNode) {
|
|
173
|
-
this.element.parentNode.removeChild(this.element);
|
|
174
|
-
this.element = null;
|
|
175
|
-
}
|
|
176
|
-
return this;
|
|
177
|
-
}
|
|
178
|
-
/* -------------------------
|
|
179
|
-
* Static Page Cleanup
|
|
180
|
-
* ------------------------- */
|
|
181
|
-
/**
|
|
182
|
-
* Remove all resources for a specific page
|
|
183
|
-
*
|
|
184
|
-
* @example
|
|
185
|
-
* Include.cleanupPage('dashboard');
|
|
186
|
-
*/
|
|
187
|
-
static cleanupPage(pageId) {
|
|
188
|
-
const resources = scopedResources.get(pageId);
|
|
189
|
-
if (!resources)
|
|
190
|
-
return;
|
|
191
|
-
resources.forEach(element => {
|
|
192
|
-
element.parentNode?.removeChild(element);
|
|
193
|
-
});
|
|
194
|
-
scopedResources.delete(pageId);
|
|
195
|
-
console.log(`✓ Cleaned up page resources: ${pageId}`);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Remove all page-scoped resources
|
|
199
|
-
*/
|
|
200
|
-
static cleanupAll() {
|
|
201
|
-
scopedResources.forEach((resources, pageId) => {
|
|
202
|
-
resources.forEach(element => {
|
|
203
|
-
element.parentNode?.removeChild(element);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
scopedResources.clear();
|
|
207
|
-
console.log('✓ Cleaned up all page-scoped resources');
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Factory function - simplified usage
|
|
212
|
-
*
|
|
213
|
-
* Usage:
|
|
214
|
-
* // Basic (auto-detects from extension)
|
|
215
|
-
* jux.include('/css/styles.css');
|
|
216
|
-
* jux.include('/js/app.js');
|
|
217
|
-
*
|
|
218
|
-
* // Page-specific with cleanup
|
|
219
|
-
* jux.include('/css/dashboard.css').forPage('dashboard');
|
|
220
|
-
* jux.include('/js/dashboard.js').forPage('dashboard');
|
|
221
|
-
*
|
|
222
|
-
* // Later cleanup:
|
|
223
|
-
* Include.cleanupPage('dashboard');
|
|
224
|
-
*
|
|
225
|
-
* // Inject into specific container
|
|
226
|
-
* jux.include('/css/widget.css').into('#widget-container');
|
|
227
|
-
*
|
|
228
|
-
* // External CDN
|
|
229
|
-
* jux.include('https://cdn.tailwindcss.com').js();
|
|
230
|
-
*
|
|
231
|
-
* // Module
|
|
232
|
-
* jux.include('/js/app.mjs').module();
|
|
233
|
-
*/
|
|
234
|
-
export function include(url, options) {
|
|
235
|
-
const inc = new Include(url, options);
|
|
236
|
-
inc.render();
|
|
237
|
-
return inc;
|
|
238
|
-
}
|