juxscript 1.0.132 ā 1.1.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/README.md +1 -32
- package/bin/cli.js +4 -2
- package/index.d.ts +200 -0
- package/index.js +96 -22
- package/juxconfig.example.js +58 -63
- package/lib/components/alert.ts +200 -0
- package/lib/components/app.ts +247 -0
- package/lib/components/badge.ts +101 -0
- package/lib/components/base/BaseComponent.ts +421 -0
- package/lib/components/base/FormInput.ts +227 -0
- package/lib/components/button.ts +178 -0
- package/lib/components/card.ts +173 -0
- package/lib/components/chart.ts +231 -0
- package/lib/components/checkbox.ts +242 -0
- package/lib/components/code.ts +123 -0
- package/lib/components/container.ts +140 -0
- package/lib/components/data.ts +135 -0
- package/lib/components/datepicker.ts +234 -0
- package/lib/components/dialog.ts +172 -0
- package/lib/components/divider.ts +100 -0
- package/lib/components/dropdown.ts +186 -0
- package/lib/components/element.ts +267 -0
- package/lib/components/fileupload.ts +309 -0
- package/lib/components/grid.ts +291 -0
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.ts +96 -0
- package/lib/components/helpers.ts +41 -0
- package/lib/components/hero.ts +224 -0
- package/lib/components/icon.ts +178 -0
- package/lib/components/icons.ts +464 -0
- package/lib/components/include.ts +410 -0
- package/lib/components/input.ts +457 -0
- package/lib/components/list.ts +419 -0
- package/lib/components/loading.ts +100 -0
- package/lib/components/menu.ts +275 -0
- package/lib/components/modal.ts +284 -0
- package/lib/components/nav.ts +257 -0
- package/lib/components/paragraph.ts +97 -0
- package/lib/components/progress.ts +159 -0
- package/lib/components/radio.ts +278 -0
- package/lib/components/req.ts +303 -0
- package/lib/components/script.ts +41 -0
- package/lib/components/select.ts +252 -0
- package/lib/components/sidebar.ts +275 -0
- package/lib/components/style.ts +41 -0
- package/lib/components/switch.ts +246 -0
- package/lib/components/table.ts +1249 -0
- package/lib/components/tabs.ts +250 -0
- package/lib/components/theme-toggle.ts +293 -0
- package/lib/components/tooltip.ts +144 -0
- package/lib/components/view.ts +190 -0
- package/lib/components/write.ts +272 -0
- package/lib/globals.d.ts +19 -5
- package/lib/layouts/default.css +260 -0
- package/lib/layouts/figma.css +334 -0
- package/lib/reactivity/state.ts +78 -0
- package/lib/utils/{fetch.js ā fetch.ts} +206 -81
- package/machinery/ast.js +347 -0
- package/machinery/build.js +466 -0
- package/machinery/compiler3.js +6 -66
- package/machinery/config.js +6 -93
- package/machinery/doc-generator.js +136 -0
- package/machinery/imports.js +155 -0
- package/machinery/server.js +166 -0
- package/machinery/ts-shim.js +46 -0
- package/machinery/watcher.js +162 -50
- package/package.json +9 -30
- package/create/index.jux +0 -77
- package/create/layout.jux +0 -18
- package/create/style.css +0 -57
- package/create/themes/assets/jux.svg +0 -34
- package/create/themes/base.css +0 -197
- package/create/themes/base2.css +0 -54
- package/create/themes/layouts/base.jux +0 -16
- package/create/themes/layouts/base_marketing.jux +0 -0
- package/create/themes/layouts/base_saas.jux +0 -0
- package/lib/componentsv2/base/BaseEngine.d.ts +0 -112
- package/lib/componentsv2/base/BaseEngine.js +0 -279
- package/lib/componentsv2/base/BaseSkin.d.ts +0 -74
- package/lib/componentsv2/base/BaseSkin.js +0 -130
- package/lib/componentsv2/base/Neighborhood.d.ts +0 -22
- package/lib/componentsv2/base/Neighborhood.js +0 -56
- package/lib/componentsv2/base/OptionsContract.d.ts +0 -20
- package/lib/componentsv2/base/OptionsContract.js +0 -107
- package/lib/componentsv2/base/State.d.ts +0 -18
- package/lib/componentsv2/base/State.js +0 -68
- package/lib/componentsv2/element/Element.d.ts +0 -30
- package/lib/componentsv2/element/Element.js +0 -50
- package/lib/componentsv2/element/ElementEngine.d.ts +0 -59
- package/lib/componentsv2/element/ElementEngine.js +0 -118
- package/lib/componentsv2/element/ElementSkin.d.ts +0 -10
- package/lib/componentsv2/element/ElementSkin.js +0 -56
- package/lib/componentsv2/element/structure.css +0 -261
- package/lib/componentsv2/grid/Grid.d.ts +0 -13
- package/lib/componentsv2/grid/Grid.js +0 -27
- package/lib/componentsv2/grid/GridEngine.d.ts +0 -77
- package/lib/componentsv2/grid/GridEngine.js +0 -153
- package/lib/componentsv2/grid/GridSkin.d.ts +0 -11
- package/lib/componentsv2/grid/GridSkin.js +0 -84
- package/lib/componentsv2/grid/structure.css +0 -27
- package/lib/componentsv2/input/Input.d.ts +0 -6
- package/lib/componentsv2/input/Input.js +0 -21
- package/lib/componentsv2/input/InputEngine.d.ts +0 -70
- package/lib/componentsv2/input/InputEngine.js +0 -143
- package/lib/componentsv2/input/InputSkin.d.ts +0 -11
- package/lib/componentsv2/input/InputSkin.js +0 -89
- package/lib/componentsv2/input/structure.css +0 -47
- package/lib/componentsv2/list/List.d.ts +0 -49
- package/lib/componentsv2/list/List.js +0 -105
- package/lib/componentsv2/list/ListEngine.d.ts +0 -121
- package/lib/componentsv2/list/ListEngine.js +0 -322
- package/lib/componentsv2/list/ListSkin.d.ts +0 -20
- package/lib/componentsv2/list/ListSkin.js +0 -345
- package/lib/componentsv2/list/structure.css +0 -359
- package/lib/componentsv2/plugins/ClientSQLitePlugin.d.ts +0 -21
- package/lib/componentsv2/plugins/ClientSQLitePlugin.js +0 -130
- package/lib/componentsv2/plugins/IndexedDBPlugin.d.ts +0 -18
- package/lib/componentsv2/plugins/IndexedDBPlugin.js +0 -75
- package/lib/componentsv2/plugins/LocalStoragePlugin.d.ts +0 -20
- package/lib/componentsv2/plugins/LocalStoragePlugin.js +0 -65
- package/lib/componentsv2/plugins/ServerSQLitePlugin.d.ts +0 -25
- package/lib/componentsv2/plugins/ServerSQLitePlugin.js +0 -70
- package/lib/componentsv2/stubs/ComponentComposition.ts.stub +0 -32
- package/lib/componentsv2/stubs/ComponentEngine.ts.stub +0 -36
- package/lib/componentsv2/stubs/ComponentSkin.ts.stub +0 -35
- package/lib/componentsv2/stubs/ComponentStructure.css.d.ts.stub +0 -2
- package/lib/componentsv2/stubs/ComponentStructure.css.stub +0 -13
- package/lib/utils/fetch.d.ts +0 -176
- package/machinery/serve.js +0 -255
- package/types/css.d.ts +0 -10
- /package/{create/themes/layouts/base_blog.jux ā machinery/bundleAssets.js} +0 -0
- /package/{create/themes/layouts/base_docs.jux ā machinery/bundleJux.js} +0 -0
- /package/{create/themes/layouts/base_login.jux ā machinery/bundleVendors.js} +0 -0
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { JuxServiceContract, BaseEngine } from '../base/BaseEngine.js';
|
|
2
|
-
export interface ServerSQLiteConfig {
|
|
3
|
-
/** The Database Driver Instance (e.g. better-sqlite3) */
|
|
4
|
-
database: any;
|
|
5
|
-
/** Optional: SQL Query to fetch data automatically */
|
|
6
|
-
query?: string;
|
|
7
|
-
/**
|
|
8
|
-
* State Binding: The property key on the Engine's state to populate.
|
|
9
|
-
* e.g., 'items' for a ListEngine, or 'rows' for a GridEngine.
|
|
10
|
-
*/
|
|
11
|
-
bindTo?: string;
|
|
12
|
-
/**
|
|
13
|
-
* Transformation Strategy:
|
|
14
|
-
* Converts a raw DB row into the shape expected by the Engine's state.
|
|
15
|
-
*/
|
|
16
|
-
mapRow?: (row: any) => any;
|
|
17
|
-
/** If true, runs the query immediately on install */
|
|
18
|
-
autoLoad?: boolean;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Server-Side SQLite Plugin
|
|
22
|
-
* Decoupled Service that injects SQL capabilities and binds data to ANY Engine state.
|
|
23
|
-
*/
|
|
24
|
-
export declare const ServerSQLitePlugin: (config: ServerSQLiteConfig) => JuxServiceContract<BaseEngine<any>>;
|
|
25
|
-
//# sourceMappingURL=ServerSQLitePlugin.d.ts.map
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-Side SQLite Plugin
|
|
3
|
-
* Decoupled Service that injects SQL capabilities and binds data to ANY Engine state.
|
|
4
|
-
*/
|
|
5
|
-
export const ServerSQLitePlugin = (config) => ({
|
|
6
|
-
name: 'server-sqlite-driver',
|
|
7
|
-
version: '2.0.0',
|
|
8
|
-
targetEnv: 'server',
|
|
9
|
-
install: (engine) => {
|
|
10
|
-
// 1. Expose SQL Capability (Mixin)
|
|
11
|
-
// Adds a .query() method to the engine instance
|
|
12
|
-
Object.assign(engine, {
|
|
13
|
-
query: (sql, params = []) => {
|
|
14
|
-
if (!config.database || typeof config.database.prepare !== 'function') {
|
|
15
|
-
throw new Error('Invalid Database Driver provided to ServerSQLitePlugin.');
|
|
16
|
-
}
|
|
17
|
-
const stmt = config.database.prepare(sql);
|
|
18
|
-
const rows = stmt.all(params);
|
|
19
|
-
// Emit audit event for queries
|
|
20
|
-
// @ts-ignore - access protected emit
|
|
21
|
-
if (typeof engine.emit === 'function')
|
|
22
|
-
engine.emit('sql:query', { sql, rows: rows.length });
|
|
23
|
-
return rows;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
// 2. Hydration Logic
|
|
27
|
-
const hydrate = () => {
|
|
28
|
-
if (!config.query)
|
|
29
|
-
return;
|
|
30
|
-
try {
|
|
31
|
-
// Use the newly injected capability
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
const rows = engine.query(config.query);
|
|
34
|
-
if (config.bindTo) {
|
|
35
|
-
const data = config.mapRow ? rows.map(config.mapRow) : rows;
|
|
36
|
-
// Generic State Update (Decoupled from ListEngine)
|
|
37
|
-
// @ts-ignore - access protected updateState
|
|
38
|
-
if (typeof engine.updateState === 'function') {
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
engine.updateState({ [config.bindTo]: data });
|
|
41
|
-
}
|
|
42
|
-
// Optional: Update loading state if the engine supports it
|
|
43
|
-
// @ts-ignore
|
|
44
|
-
if (typeof engine.loading === 'function')
|
|
45
|
-
engine.loading(false);
|
|
46
|
-
// Emit data event for loose coupling
|
|
47
|
-
// @ts-ignore
|
|
48
|
-
if (typeof engine.emit === 'function')
|
|
49
|
-
engine.emit('plugin:data', { source: 'sqlite', count: data.length });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
console.error('[ServerSQLitePlugin] Hydration Error:', err.message);
|
|
54
|
-
// @ts-ignore
|
|
55
|
-
if (typeof engine.loading === 'function')
|
|
56
|
-
engine.loading(false);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
// 3. Auto-Start
|
|
60
|
-
if (config.autoLoad) {
|
|
61
|
-
// @ts-ignore
|
|
62
|
-
if (typeof engine.loading === 'function')
|
|
63
|
-
engine.loading(true);
|
|
64
|
-
hydrate();
|
|
65
|
-
}
|
|
66
|
-
// 4. Listen for Reload Signal
|
|
67
|
-
engine.on('db:reload', hydrate);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
//# sourceMappingURL=ServerSQLitePlugin.js.map
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { [% ComponentName %]Engine, [% ComponentName %]Options } from './engine.js';
|
|
2
|
-
import { [% ComponentName %]Skin } from './skin.js';
|
|
3
|
-
|
|
4
|
-
export type [% ComponentName %]Component = [% ComponentName %]Engine & {
|
|
5
|
-
render: (targetId: string | HTMLElement) => [% ComponentName %]Component;
|
|
6
|
-
injectCSS: (id: string, cssContent: string) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export function [% ComponentName %](id: string, options: [% ComponentName %]Options = {}): [% ComponentName %]Component {
|
|
10
|
-
const engine = new [% ComponentName %]Engine(id, options);
|
|
11
|
-
|
|
12
|
-
if (typeof window !== 'undefined') {
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
window.juxEngines = window.juxEngines || {};
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
window.juxEngines[id] = engine;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const skin = new [% ComponentName %]Skin(engine);
|
|
20
|
-
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
engine.render = (targetId: string | HTMLElement) => {
|
|
23
|
-
const target = typeof targetId === 'string' ? document.getElementById(targetId) : targetId;
|
|
24
|
-
if (target) skin.renderSkin(target);
|
|
25
|
-
return engine as [% ComponentName %]Component;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
// @ts-ignore
|
|
29
|
-
engine.injectCSS = (id, css) => skin.injectCSS(id, css);
|
|
30
|
-
|
|
31
|
-
return engine as [% ComponentName %]Component;
|
|
32
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { BaseEngine, BaseState } from '../base/BaseEngine.js';
|
|
2
|
-
|
|
3
|
-
export interface [% ComponentName %]State extends BaseState {
|
|
4
|
-
// TODO: Define your state properties
|
|
5
|
-
text: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface [% ComponentName %]Options {
|
|
9
|
-
// TODO: Define configuration options
|
|
10
|
-
text?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class [% ComponentName %]Engine extends BaseEngine<[% ComponentName %]State, [% ComponentName %]Options> {
|
|
14
|
-
constructor(id: string, options: [% ComponentName %]Options = {}) {
|
|
15
|
-
super(id, options);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
protected prepareState(id: string, options: [% ComponentName %]Options): [% ComponentName %]State {
|
|
19
|
-
return {
|
|
20
|
-
id,
|
|
21
|
-
classes: ['jux-[% component-name %]'],
|
|
22
|
-
visible: true,
|
|
23
|
-
disabled: false,
|
|
24
|
-
loading: false,
|
|
25
|
-
attributes: {},
|
|
26
|
-
text: options.text || 'Hello World'
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Example Mutator
|
|
31
|
-
setText(value: string): this {
|
|
32
|
-
this.updateState({ text: value });
|
|
33
|
-
this.emit('textChange', { value });
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { BaseSkin } from '../base/BaseSkin.js';
|
|
2
|
-
import { [% ComponentName %]Engine, [% ComponentName %]State } from './engine.js';
|
|
3
|
-
import structureCss from './structure.css';
|
|
4
|
-
|
|
5
|
-
export class [% ComponentName %]Skin extends BaseSkin<[% ComponentName %]State, [% ComponentName %]Engine> {
|
|
6
|
-
constructor(engine: [% ComponentName %]Engine) {
|
|
7
|
-
super(engine);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Define the structural CSS for this component.
|
|
12
|
-
*/
|
|
13
|
-
protected get structureCss(): string {
|
|
14
|
-
return structureCss;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
protected bindEvents(root: HTMLElement): void {
|
|
18
|
-
// TODO: Bind DOM events to Engine methods
|
|
19
|
-
root.addEventListener('click', () => {
|
|
20
|
-
console.log('[% ComponentName %] clicked');
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
protected updateSkin(state: [% ComponentName %]State): void {
|
|
25
|
-
if (!this.root) return;
|
|
26
|
-
this.applySkinAttributes(this.root, state);
|
|
27
|
-
|
|
28
|
-
// TODO: Render state to DOM
|
|
29
|
-
this.root.textContent = state.text;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
protected createRoot(): HTMLElement {
|
|
33
|
-
return document.createElement('div');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
.jux-[% component-name %] {
|
|
2
|
-
display: block;
|
|
3
|
-
padding: var(--space-md);
|
|
4
|
-
border: 1px solid var(--color-border);
|
|
5
|
-
border-radius: var(--radius-sm);
|
|
6
|
-
background-color: var(--color-surface-base);
|
|
7
|
-
color: var(--color-text-primary);
|
|
8
|
-
transition: all var(--transition-fast);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.jux-[% component-name %]:hover {
|
|
12
|
-
background-color: var(--color-surface-hover);
|
|
13
|
-
}
|
package/lib/utils/fetch.d.ts
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Jux Fetch Utility
|
|
3
|
-
*
|
|
4
|
-
* A lightweight fetch wrapper with sensible defaults, error handling, and method chaining.
|
|
5
|
-
* Includes configuration helpers for juxconfig.js integration.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* // Configure once (optional)
|
|
9
|
-
* jux.fetch.config({
|
|
10
|
-
* baseUrl: 'https://api.example.com',
|
|
11
|
-
* credentials: 'include',
|
|
12
|
-
* timeout: 10000,
|
|
13
|
-
* log: 'errors',
|
|
14
|
-
* onUnauthorized: () => window.location.href = '/login'
|
|
15
|
-
* });
|
|
16
|
-
*
|
|
17
|
-
* // Simple GET
|
|
18
|
-
* const { data, error } = await jux.fetch('/users').send();
|
|
19
|
-
*
|
|
20
|
-
* // Method chaining
|
|
21
|
-
* const { data, error } = await jux.fetch('/users')
|
|
22
|
-
* .method('POST')
|
|
23
|
-
* .body({ name: 'John' })
|
|
24
|
-
* .params({ limit: 10 })
|
|
25
|
-
* .timeout(5000)
|
|
26
|
-
* .log(true)
|
|
27
|
-
* .send();
|
|
28
|
-
*
|
|
29
|
-
* // With juxconfig services
|
|
30
|
-
* const { data } = await jux.fetch('/users')
|
|
31
|
-
* .baseUrl(jux.fetch.getServiceUrl('database'))
|
|
32
|
-
* .send();
|
|
33
|
-
*
|
|
34
|
-
* // Service client helper
|
|
35
|
-
* const db = jux.fetch.serviceClient('database');
|
|
36
|
-
* const { data } = await db.fetch('/users').send();
|
|
37
|
-
*/
|
|
38
|
-
export type LogLevel = boolean | 'errors';
|
|
39
|
-
export interface FetchConfig {
|
|
40
|
-
baseUrl?: string;
|
|
41
|
-
credentials?: RequestCredentials;
|
|
42
|
-
headers?: Record<string, string>;
|
|
43
|
-
timeout?: number;
|
|
44
|
-
log?: LogLevel;
|
|
45
|
-
onUnauthorized?: () => void;
|
|
46
|
-
onError?: (error: FetchError) => void;
|
|
47
|
-
}
|
|
48
|
-
export interface FetchOptions extends Omit<RequestInit, 'body'> {
|
|
49
|
-
params?: Record<string, any>;
|
|
50
|
-
body?: any;
|
|
51
|
-
timeout?: number;
|
|
52
|
-
log?: LogLevel;
|
|
53
|
-
onUnauthorized?: () => void;
|
|
54
|
-
onError?: (error: FetchError) => void;
|
|
55
|
-
parseResponse?: boolean;
|
|
56
|
-
}
|
|
57
|
-
export interface FetchError {
|
|
58
|
-
message: string;
|
|
59
|
-
status?: number;
|
|
60
|
-
statusText?: string;
|
|
61
|
-
data?: any;
|
|
62
|
-
}
|
|
63
|
-
export interface FetchResult<T = any> {
|
|
64
|
-
data: T | null;
|
|
65
|
-
error: FetchError | null;
|
|
66
|
-
status: number;
|
|
67
|
-
response: Response;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Configure global fetch defaults
|
|
71
|
-
*/
|
|
72
|
-
export declare function configureFetch(config: FetchConfig): void;
|
|
73
|
-
/**
|
|
74
|
-
* FetchBuilder class for method chaining
|
|
75
|
-
*/
|
|
76
|
-
declare class FetchBuilder<T = any> {
|
|
77
|
-
url: string;
|
|
78
|
-
options: FetchOptions;
|
|
79
|
-
constructor(url: string, options?: FetchOptions);
|
|
80
|
-
method(value: string): this;
|
|
81
|
-
body(value: any): this;
|
|
82
|
-
params(value: Record<string, any>): this;
|
|
83
|
-
headers(value: Record<string, string>): this;
|
|
84
|
-
header(key: string, value: string): this;
|
|
85
|
-
timeout(value: number): this;
|
|
86
|
-
credentials(value: RequestCredentials): this;
|
|
87
|
-
log(value: LogLevel): this;
|
|
88
|
-
parseResponse(value: boolean): this;
|
|
89
|
-
onUnauthorized(callback: () => void): this;
|
|
90
|
-
onError(callback: (error: FetchError) => void): this;
|
|
91
|
-
/**
|
|
92
|
-
* Execute the fetch request
|
|
93
|
-
*/
|
|
94
|
-
send(): Promise<FetchResult<T>>;
|
|
95
|
-
/**
|
|
96
|
-
* Alias for send()
|
|
97
|
-
*/
|
|
98
|
-
fetch(): Promise<FetchResult<T>>;
|
|
99
|
-
/**
|
|
100
|
-
* Make the builder thenable (Promise-like) so it can be awaited directly
|
|
101
|
-
* This allows: await jux.fetch('/users') without needing .send()
|
|
102
|
-
*/
|
|
103
|
-
then<TResult1 = FetchResult<T>, TResult2 = never>(onfulfilled?: ((value: FetchResult<T>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
104
|
-
/**
|
|
105
|
-
* Make the builder catchable for Promise.catch()
|
|
106
|
-
*/
|
|
107
|
-
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<FetchResult<T> | TResult>;
|
|
108
|
-
/**
|
|
109
|
-
* Make the builder finally-able for Promise.finally()
|
|
110
|
-
*/
|
|
111
|
-
finally(onfinally?: (() => void) | null): Promise<FetchResult<T>>;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Create a fetch builder
|
|
115
|
-
*/
|
|
116
|
-
export declare function juxFetch<T = any>(url: string, options?: FetchOptions): FetchBuilder<T>;
|
|
117
|
-
/**
|
|
118
|
-
* Convenience methods for common HTTP verbs
|
|
119
|
-
*/
|
|
120
|
-
export declare const fetchHelpers: {
|
|
121
|
-
get: <T = any>(url: string, options?: Omit<FetchOptions, "method">) => FetchBuilder<T>;
|
|
122
|
-
post: <T = any>(url: string, body?: any, options?: Omit<FetchOptions, "method" | "body">) => FetchBuilder<T>;
|
|
123
|
-
put: <T = any>(url: string, body?: any, options?: Omit<FetchOptions, "method" | "body">) => FetchBuilder<T>;
|
|
124
|
-
patch: <T = any>(url: string, body?: any, options?: Omit<FetchOptions, "method" | "body">) => FetchBuilder<T>;
|
|
125
|
-
delete: <T = any>(url: string, options?: Omit<FetchOptions, "method">) => FetchBuilder<T>;
|
|
126
|
-
};
|
|
127
|
-
/**
|
|
128
|
-
* Fetch multiple URLs in parallel
|
|
129
|
-
*/
|
|
130
|
-
export declare function fetchAll<T = any>(urls: string[], options?: FetchOptions): Promise<FetchResult<T>[]>;
|
|
131
|
-
/**
|
|
132
|
-
* Get a service URL from window.juxConfig
|
|
133
|
-
*/
|
|
134
|
-
export declare function getServiceUrl(serviceName: string): string | null;
|
|
135
|
-
/**
|
|
136
|
-
* Create a fetch instance preconfigured for a specific service
|
|
137
|
-
*
|
|
138
|
-
* Usage:
|
|
139
|
-
* const api = jux.fetch.serviceClient('database');
|
|
140
|
-
* const { data } = await api.fetch('/users').send();
|
|
141
|
-
*/
|
|
142
|
-
export declare function serviceClient(serviceName: string): {
|
|
143
|
-
fetch: (url: string, options?: any) => FetchBuilder<any>;
|
|
144
|
-
baseUrl: string | null;
|
|
145
|
-
};
|
|
146
|
-
/**
|
|
147
|
-
* Setup fetch from juxconfig
|
|
148
|
-
* Call this in your bootstrap function
|
|
149
|
-
*
|
|
150
|
-
* Usage:
|
|
151
|
-
* export default {
|
|
152
|
-
* bootstrap: [
|
|
153
|
-
* async function initFetch() {
|
|
154
|
-
* await jux.fetch.setupConfig();
|
|
155
|
-
* }
|
|
156
|
-
* ]
|
|
157
|
-
* };
|
|
158
|
-
*/
|
|
159
|
-
export declare function setupConfig(): Promise<{
|
|
160
|
-
services: any;
|
|
161
|
-
getServiceUrl: typeof getServiceUrl;
|
|
162
|
-
} | undefined>;
|
|
163
|
-
export declare const fetchAPI: typeof juxFetch & {
|
|
164
|
-
all: typeof fetchAll;
|
|
165
|
-
get: <T = any>(url: string, options?: Omit<FetchOptions, "method">) => FetchBuilder<T>;
|
|
166
|
-
post: <T = any>(url: string, body?: any, options?: Omit<FetchOptions, "method" | "body">) => FetchBuilder<T>;
|
|
167
|
-
put: <T = any>(url: string, body?: any, options?: Omit<FetchOptions, "method" | "body">) => FetchBuilder<T>;
|
|
168
|
-
patch: <T = any>(url: string, body?: any, options?: Omit<FetchOptions, "method" | "body">) => FetchBuilder<T>;
|
|
169
|
-
delete: <T = any>(url: string, options?: Omit<FetchOptions, "method">) => FetchBuilder<T>;
|
|
170
|
-
config: typeof configureFetch;
|
|
171
|
-
setupConfig: typeof setupConfig;
|
|
172
|
-
getServiceUrl: typeof getServiceUrl;
|
|
173
|
-
serviceClient: typeof serviceClient;
|
|
174
|
-
};
|
|
175
|
-
export {};
|
|
176
|
-
//# sourceMappingURL=fetch.d.ts.map
|
package/machinery/serve.js
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import http from 'http';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { WebSocketServer } from 'ws';
|
|
7
|
-
import { createWatcher } from './watcher.js';
|
|
8
|
-
import { JuxCompiler } from './compiler3.js';
|
|
9
|
-
|
|
10
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
const __dirname = path.dirname(__filename);
|
|
12
|
-
|
|
13
|
-
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
14
|
-
// CONFIGURATION
|
|
15
|
-
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
16
|
-
const args = process.argv.slice(2);
|
|
17
|
-
const HOT_RELOAD = args.includes('--hot') || args.includes('-h') || args.includes('--watch');
|
|
18
|
-
|
|
19
|
-
// Extract port from args (e.g., --port=3000 or -p 3000)
|
|
20
|
-
function getArgValue(flag, shortFlag, defaultValue) {
|
|
21
|
-
for (let i = 0; i < args.length; i++) {
|
|
22
|
-
if (args[i].startsWith(`${flag}=`)) return args[i].split('=')[1];
|
|
23
|
-
if (args[i].startsWith(`${shortFlag}=`)) return args[i].split('=')[1];
|
|
24
|
-
if ((args[i] === flag || args[i] === shortFlag) && args[i + 1]) return args[i + 1];
|
|
25
|
-
}
|
|
26
|
-
return defaultValue;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const PORT = parseInt(getArgValue('--port', '-p', process.env.PORT || '3000'));
|
|
30
|
-
const WS_PORT = parseInt(getArgValue('--ws-port', '-w', process.env.WS_PORT || String(PORT + 1)));
|
|
31
|
-
|
|
32
|
-
// Resolve paths relative to CWD (user's project)
|
|
33
|
-
const PROJECT_ROOT = process.cwd();
|
|
34
|
-
const DIST_DIR = path.resolve(PROJECT_ROOT, '.jux-dist');
|
|
35
|
-
const SRC_DIR = path.resolve(PROJECT_ROOT, 'jux');
|
|
36
|
-
|
|
37
|
-
const app = express();
|
|
38
|
-
let lastBuildResult = { success: true, errors: [] };
|
|
39
|
-
|
|
40
|
-
// Check if dist directory exists - if not, try to build first
|
|
41
|
-
if (!fs.existsSync(DIST_DIR) || !fs.existsSync(path.join(DIST_DIR, 'index.html'))) {
|
|
42
|
-
console.log('ā ļø Dist directory not found. Running initial build...');
|
|
43
|
-
|
|
44
|
-
const compiler = new JuxCompiler({
|
|
45
|
-
srcDir: SRC_DIR,
|
|
46
|
-
distDir: DIST_DIR
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
const result = await compiler.build();
|
|
51
|
-
lastBuildResult = result;
|
|
52
|
-
|
|
53
|
-
if (!result.success) {
|
|
54
|
-
console.log('\nā Initial build failed. Starting server to show error overlay.\n');
|
|
55
|
-
}
|
|
56
|
-
} catch (err) {
|
|
57
|
-
console.error('ā Initial build failed:', err.message);
|
|
58
|
-
lastBuildResult = { success: false, errors: [{ message: err.message }] };
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (!fs.existsSync(DIST_DIR)) {
|
|
63
|
-
fs.mkdirSync(DIST_DIR, { recursive: true });
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
app.use((req, res, next) => {
|
|
67
|
-
res.setHeader('Cache-Control', 'no-store');
|
|
68
|
-
next();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
app.use((req, res, next) => {
|
|
72
|
-
if (req.path.endsWith('.js')) {
|
|
73
|
-
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
74
|
-
}
|
|
75
|
-
next();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
app.get('/favicon.ico', (req, res) => res.status(204).end());
|
|
79
|
-
app.get('/favicon.png', (req, res) => res.status(204).end());
|
|
80
|
-
|
|
81
|
-
app.get('/__jux_sources.json', (req, res) => {
|
|
82
|
-
const snapshotPath = path.join(DIST_DIR, '__jux_sources.json');
|
|
83
|
-
if (fs.existsSync(snapshotPath)) {
|
|
84
|
-
res.setHeader('Content-Type', 'application/json');
|
|
85
|
-
res.sendFile(snapshotPath);
|
|
86
|
-
} else {
|
|
87
|
-
res.json({});
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
const hotReloadScript = `
|
|
92
|
-
<script>
|
|
93
|
-
(function() {
|
|
94
|
-
var ws = new WebSocket('ws://localhost:${WS_PORT}');
|
|
95
|
-
ws.onopen = function() { console.log('š„ Hot reload connected'); };
|
|
96
|
-
ws.onmessage = function(e) {
|
|
97
|
-
var data = JSON.parse(e.data);
|
|
98
|
-
if (data.type === 'reload') location.reload();
|
|
99
|
-
else if (data.type === 'build-error') console.error('ā Build error:', data.errors);
|
|
100
|
-
};
|
|
101
|
-
ws.onclose = function() { setTimeout(function() { location.reload(); }, 2000); };
|
|
102
|
-
})();
|
|
103
|
-
</script>
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
function getErrorPageHtml(errors) {
|
|
107
|
-
return `<!DOCTYPE html>
|
|
108
|
-
<html lang="en">
|
|
109
|
-
<head>
|
|
110
|
-
<meta charset="UTF-8">
|
|
111
|
-
<title>JUX Build Error</title>
|
|
112
|
-
<style>
|
|
113
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
114
|
-
body { font-family: monospace; background: #1a1a2e; color: #eee; min-height: 100vh; padding: 40px; }
|
|
115
|
-
.container { max-width: 800px; margin: 0 auto; }
|
|
116
|
-
h1 { color: #ff6b6b; margin-bottom: 8px; }
|
|
117
|
-
.subtitle { color: #888; margin-bottom: 30px; }
|
|
118
|
-
.error-card { background: #16213e; padding: 16px 20px; border-radius: 8px; margin-bottom: 12px; border-left: 4px solid #ff6b6b; }
|
|
119
|
-
.error-header { color: #ff6b6b; font-weight: bold; margin-bottom: 8px; }
|
|
120
|
-
.error-code { background: #0f0f23; padding: 12px; border-radius: 4px; font-size: 13px; color: #888; }
|
|
121
|
-
</style>
|
|
122
|
-
</head>
|
|
123
|
-
<body>
|
|
124
|
-
<div class="container">
|
|
125
|
-
<h1>š Build Failed</h1>
|
|
126
|
-
<p class="subtitle">Fix the errors below and save to rebuild.</p>
|
|
127
|
-
${errors.map(err => `
|
|
128
|
-
<div class="error-card">
|
|
129
|
-
<div class="error-header">${err.view ? `[${err.view}] ` : ''}${err.message}</div>
|
|
130
|
-
${err.code ? `<pre class="error-code">${err.code}</pre>` : ''}
|
|
131
|
-
</div>
|
|
132
|
-
`).join('')}
|
|
133
|
-
</div>
|
|
134
|
-
${HOT_RELOAD ? `<script>
|
|
135
|
-
var ws = new WebSocket('ws://localhost:${WS_PORT}');
|
|
136
|
-
ws.onmessage = function(e) { if (JSON.parse(e.data).type === 'reload') location.reload(); };
|
|
137
|
-
</script>` : ''}
|
|
138
|
-
</body>
|
|
139
|
-
</html>`;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (HOT_RELOAD) {
|
|
143
|
-
app.get(['/', '/index.html'], (req, res) => {
|
|
144
|
-
const indexPath = path.join(DIST_DIR, 'index.html');
|
|
145
|
-
|
|
146
|
-
if (!fs.existsSync(indexPath) || !lastBuildResult.success) {
|
|
147
|
-
return res.send(getErrorPageHtml(lastBuildResult.errors));
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
let html = fs.readFileSync(indexPath, 'utf8');
|
|
151
|
-
html = html.replace('</body>', hotReloadScript + '</body>');
|
|
152
|
-
res.setHeader('Content-Type', 'text/html');
|
|
153
|
-
res.send(html);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
app.use(express.static(DIST_DIR));
|
|
158
|
-
|
|
159
|
-
app.get('*', (req, res) => {
|
|
160
|
-
if (path.extname(req.path) && req.path !== '/') {
|
|
161
|
-
return res.status(404).send('Not found');
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const indexPath = path.join(DIST_DIR, 'index.html');
|
|
165
|
-
|
|
166
|
-
if (!fs.existsSync(indexPath) || !lastBuildResult.success) {
|
|
167
|
-
return res.send(getErrorPageHtml(lastBuildResult.errors));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (HOT_RELOAD) {
|
|
171
|
-
let html = fs.readFileSync(indexPath, 'utf8');
|
|
172
|
-
html = html.replace('</body>', hotReloadScript + '</body>');
|
|
173
|
-
res.setHeader('Content-Type', 'text/html');
|
|
174
|
-
res.send(html);
|
|
175
|
-
} else {
|
|
176
|
-
res.sendFile(indexPath);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const server = http.createServer(app);
|
|
181
|
-
let wss = null;
|
|
182
|
-
let watcher = null;
|
|
183
|
-
|
|
184
|
-
if (HOT_RELOAD) {
|
|
185
|
-
wss = new WebSocketServer({ port: WS_PORT });
|
|
186
|
-
const clients = new Set();
|
|
187
|
-
|
|
188
|
-
wss.on('connection', (ws) => {
|
|
189
|
-
clients.add(ws);
|
|
190
|
-
ws.on('close', () => clients.delete(ws));
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
const broadcast = (message) => {
|
|
194
|
-
const data = JSON.stringify(message);
|
|
195
|
-
clients.forEach(client => {
|
|
196
|
-
if (client.readyState === 1) client.send(data);
|
|
197
|
-
});
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
const compiler = new JuxCompiler({
|
|
201
|
-
srcDir: SRC_DIR,
|
|
202
|
-
distDir: DIST_DIR
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
watcher = createWatcher(SRC_DIR, {
|
|
206
|
-
onChange: async (changedFiles) => {
|
|
207
|
-
console.log('š Rebuilding...');
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
const result = await compiler.build();
|
|
211
|
-
lastBuildResult = result;
|
|
212
|
-
|
|
213
|
-
if (!result.success) {
|
|
214
|
-
console.error('ā Rebuild failed');
|
|
215
|
-
broadcast({ type: 'build-error', errors: result.errors });
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
console.log('ā
Rebuild complete');
|
|
220
|
-
broadcast({ type: 'reload', files: changedFiles });
|
|
221
|
-
} catch (err) {
|
|
222
|
-
console.error('ā Rebuild failed:', err.message);
|
|
223
|
-
lastBuildResult = { success: false, errors: [{ message: err.message }] };
|
|
224
|
-
broadcast({ type: 'build-error', errors: [{ message: err.message }] });
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
onReady: () => {
|
|
228
|
-
console.log(`š Watching: ${SRC_DIR}`);
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
server.listen(PORT, () => {
|
|
234
|
-
console.log(`\nš JUX Server running at http://localhost:${PORT}`);
|
|
235
|
-
if (HOT_RELOAD) {
|
|
236
|
-
console.log(`š„ Hot reload: ws://localhost:${WS_PORT}`);
|
|
237
|
-
}
|
|
238
|
-
if (!lastBuildResult.success) {
|
|
239
|
-
console.log(`ā ļø Build has errors - fix them and save\n`);
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
const shutdown = () => {
|
|
244
|
-
console.log('\nš Shutting down...');
|
|
245
|
-
if (watcher) watcher.close();
|
|
246
|
-
if (wss) {
|
|
247
|
-
wss.clients.forEach(client => client.terminate());
|
|
248
|
-
wss.close();
|
|
249
|
-
}
|
|
250
|
-
server.close(() => process.exit(0));
|
|
251
|
-
setTimeout(() => process.exit(0), 2000);
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
process.on('SIGINT', shutdown);
|
|
255
|
-
process.on('SIGTERM', shutdown);
|
package/types/css.d.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|