@webjsdev/core 0.7.1

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 ADDED
@@ -0,0 +1,55 @@
1
+ # @webjsdev/core
2
+
3
+ Isomorphic core runtime for [webjs](https://github.com/vivek7405/webjs), the
4
+ AI-first, web-components-first, no-build web framework.
5
+
6
+ This package ships the tagged-template `html` / `css` helpers, the
7
+ `WebComponent` base class, the client and server renderers (with Declarative
8
+ Shadow DOM support), directives, context protocol, the `Task` controller, and
9
+ the client-side navigation router.
10
+
11
+ Not intended for direct install. You'll usually get it as a transitive dep
12
+ when you scaffold an app with [`@webjsdev/cli`](https://www.npmjs.com/package/@webjsdev/cli).
13
+
14
+ ## Install
15
+
16
+ ```sh
17
+ npm install @webjsdev/core
18
+ ```
19
+
20
+ ## Use
21
+
22
+ ```js
23
+ import { html, css, WebComponent } from '@webjsdev/core';
24
+
25
+ class Counter extends WebComponent {
26
+ static properties = { count: { type: Number } };
27
+ static styles = css`button { padding: 8px 12px; }`;
28
+
29
+ render() {
30
+ return html`<button @click=${() => this.count++}>${this.count}</button>`;
31
+ }
32
+ }
33
+ Counter.register('x-counter');
34
+ ```
35
+
36
+ `Class.register('tag-name')` is the webjs idiom. It calls
37
+ `customElements.define()` under the hood and adds tag validation,
38
+ registry bookkeeping (needed for lazy-loading), and a dev-time
39
+ double-register warning. Plain `customElements.define('x-counter',
40
+ Counter)` works identically.
41
+
42
+ Side-channel imports for optional features:
43
+
44
+ ```js
45
+ import '@webjsdev/core/client-router'; // SPA-style link interception
46
+ import { unsafeHTML } from '@webjsdev/core/directives';
47
+ import { createContext } from '@webjsdev/core/context';
48
+ import { Task } from '@webjsdev/core/task';
49
+ ```
50
+
51
+ See the full framework docs at https://github.com/vivek7405/webjs.
52
+
53
+ ## License
54
+
55
+ MIT
package/index.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Public type surface for `webjs`.
3
+ *
4
+ * The runtime is packages/core/index.js (JSDoc-annotated JavaScript); this
5
+ * overlay exists so TypeScript-based editors (tsserver under VS Code,
6
+ * Neovim, Zed, WebStorm) resolve richer types than JSDoc alone can express
7
+ * - specifically the generic component factory and property-descriptor
8
+ * inference helpers. Zero runtime cost.
9
+ */
10
+
11
+ export * from './src/component.d.ts';
12
+
13
+ export { html, isTemplate, MARKER } from './src/html.js';
14
+ export { css, isCSS, adoptStyles, stylesToString } from './src/css.js';
15
+ export { register, lookup, lookupModuleUrl, isLazy, allTags, primeModuleUrl, tagOf } from './src/registry.js';
16
+ export { renderToString, renderToStream } from './src/render-server.js';
17
+ export { render } from './src/render-client.js';
18
+ export { escapeText, escapeAttr } from './src/escape.js';
19
+ export { notFound, redirect, isNotFound, isRedirect } from './src/nav.js';
20
+ export { expose, getExposed } from './src/expose.js';
21
+ export { repeat, isRepeat } from './src/repeat.js';
22
+ export { Suspense, isSuspense } from './src/suspense.js';
23
+ export { connectWS } from './src/websocket-client.js';
24
+ export { richFetch } from './src/rich-fetch.js';
25
+ export { enableClientRouter, disableClientRouter, navigate } from './src/router-client.js';
26
+ export { unsafeHTML, isUnsafeHTML, live, isLive } from './src/directives.js';
27
+ export { createContext, ContextProvider, ContextConsumer, ContextRequestEvent } from './src/context.js';
28
+ export { Task, TaskStatus } from './src/task.js';
package/index.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * webjs/core public surface.
3
+ *
4
+ * Isomorphic: this module is safe to import on both server and client.
5
+ * The client renderer is lazy-loaded by the WebComponent base. The server
6
+ * renderer is only reached on the server.
7
+ */
8
+
9
+ export { html, isTemplate, MARKER } from './src/html.js';
10
+ export { css, isCSS, adoptStyles, stylesToString } from './src/css.js';
11
+ export { WebComponent } from './src/component.js';
12
+ export { register, lookup, lookupModuleUrl, isLazy, allTags, primeModuleUrl, tagOf } from './src/registry.js';
13
+ export { renderToString, renderToStream } from './src/render-server.js';
14
+ export { render } from './src/render-client.js';
15
+ export { escapeText, escapeAttr } from './src/escape.js';
16
+ export { notFound, redirect, isNotFound, isRedirect } from './src/nav.js';
17
+ export { expose, getExposed } from './src/expose.js';
18
+ export { repeat, isRepeat } from './src/repeat.js';
19
+ export { Suspense, isSuspense } from './src/suspense.js';
20
+ export { connectWS } from './src/websocket-client.js';
21
+ export { richFetch } from './src/rich-fetch.js';
22
+ export {
23
+ stringify, parse,
24
+ serialize, deserialize,
25
+ } from './src/serialize.js';
26
+ export { enableClientRouter, disableClientRouter, navigate, revalidate } from './src/router-client.js';
27
+ export { WebjsFrame } from './src/webjs-frame.js';
28
+
29
+ // Signals (TC39 Stage-1 shape), also available via '@webjsdev/core/signals'
30
+ export { signal, computed, effect, batch, isSignal, Signal } from './src/signal.js';
31
+
32
+ // Directives, also available via '@webjsdev/core/directives'
33
+ export { unsafeHTML, isUnsafeHTML, live, isLive } from './src/directives.js';
34
+
35
+ // Context Protocol, also available via '@webjsdev/core/context'
36
+ export { createContext, ContextProvider, ContextConsumer, ContextRequestEvent } from './src/context.js';
37
+
38
+ // Task controller, also available via '@webjsdev/core/task'
39
+ export { Task, TaskStatus } from './src/task.js';
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@webjsdev/core",
3
+ "version": "0.7.1",
4
+ "type": "module",
5
+ "description": "webjs core runtime - html/css tags, WebComponent base, isomorphic renderers",
6
+ "types": "./index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./index.d.ts",
10
+ "default": "./index.js"
11
+ },
12
+ "./client": "./src/render-client.js",
13
+ "./server": "./src/render-server.js",
14
+ "./component": {
15
+ "types": "./src/component.d.ts",
16
+ "default": "./src/component.js"
17
+ },
18
+ "./registry": "./src/registry.js",
19
+ "./client-router": "./src/router-client.js",
20
+ "./signals": "./src/signal.js"
21
+ },
22
+ "files": [
23
+ "index.js",
24
+ "index.d.ts",
25
+ "src",
26
+ "README.md"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/vivek7405/webjs.git",
34
+ "directory": "packages/core"
35
+ },
36
+ "homepage": "https://github.com/vivek7405/webjs#readme",
37
+ "bugs": "https://github.com/vivek7405/webjs/issues",
38
+ "license": "MIT",
39
+ "keywords": [
40
+ "webjs",
41
+ "web-components",
42
+ "ssr",
43
+ "framework",
44
+ "no-build"
45
+ ]
46
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * TypeScript overlay for packages/core/src/component.js.
3
+ *
4
+ * The runtime is JSDoc-authored JavaScript; this file exists so editors
5
+ * (tsserver: used by VS Code, Neovim, Zed, WebStorm) resolve imports
6
+ * with full type information. Without this overlay, `declare foo: Foo`
7
+ * would type the field but the surrounding class (`this.requestUpdate`,
8
+ * lifecycle hooks, controllers) would be weakly typed. Zero runtime
9
+ * cost: nothing in this file ships to the browser.
10
+ */
11
+
12
+ import type { CSSResult } from './css.js';
13
+ import type { TemplateResult } from './html.js';
14
+
15
+ /** Any constructor the framework accepts as the `type:` field of a property. */
16
+ export type PropertyConstructor<T = unknown> =
17
+ | StringConstructor
18
+ | NumberConstructor
19
+ | BooleanConstructor
20
+ | ObjectConstructor
21
+ | ArrayConstructor
22
+ | (new (...args: any[]) => T)
23
+ | ((v: any) => T);
24
+
25
+ /** Runtime-level property declaration: matches `static properties = { … }`. */
26
+ export interface PropertyDeclaration<T = unknown> {
27
+ /** Constructor used for string → value coercion when the attribute changes. */
28
+ type?: PropertyConstructor<T>;
29
+ /** Write property changes back to the HTML attribute (kebab-cased). */
30
+ reflect?: boolean;
31
+ /** Internal-only: no attribute, no reflection, but still reactive. */
32
+ state?: boolean;
33
+ /** Rename the attribute, or pass `false` to suppress it entirely. */
34
+ attribute?: string | false;
35
+ /** Custom attribute ⇄ property serialisation. Takes precedence over `type`. */
36
+ converter?: {
37
+ fromAttribute?: (value: string | null, type?: PropertyConstructor<T>) => T;
38
+ toAttribute?: (value: T, type?: PropertyConstructor<T>) => string | null;
39
+ };
40
+ /** Custom dirty check. Return `true` to schedule an update. */
41
+ hasChanged?: (newValue: T, oldValue: T) => boolean;
42
+ }
43
+
44
+ /** Reactive controller protocol (Lit-compatible). */
45
+ export interface ReactiveController {
46
+ hostConnected?(): void;
47
+ hostDisconnected?(): void;
48
+ hostUpdate?(): void;
49
+ hostUpdated?(): void;
50
+ }
51
+
52
+ /**
53
+ * Base class for interactive web components.
54
+ *
55
+ * Declare runtime behaviour via `static properties = { … }` and type
56
+ * each field with a sibling `declare foo: Foo`:
57
+ *
58
+ * class StudentCard extends WebComponent {
59
+ * static properties = { student: { type: Object } };
60
+ * declare student: Student;
61
+ * render() { return html`<p>${this.student.name}</p>`; }
62
+ * }
63
+ * StudentCard.register('student-card');
64
+ *
65
+ * The `declare` field has no runtime cost: it tells TypeScript the
66
+ * field's type without emitting a class-field initializer that would
67
+ * clobber the reactive accessor the framework installs via
68
+ * `Object.defineProperty` in the constructor.
69
+ *
70
+ * See the Editor Setup doc for tooling that gives attribute/tag
71
+ * intelligence inside `html\`…\`` templates.
72
+ */
73
+ export abstract class WebComponent extends HTMLElement {
74
+ static shadow: boolean;
75
+ static hydrate: 'visible' | undefined;
76
+ static properties: Record<string, PropertyDeclaration>;
77
+ static styles: CSSResult | CSSResult[] | null;
78
+ static lazy?: boolean;
79
+ /** Register this class as a custom element under `tag`. Tag must contain a hyphen. */
80
+ static register(tag: string): void;
81
+ static readonly observedAttributes: string[];
82
+
83
+ /**
84
+ * Schedule a re-render. Optionally record a property change so lifecycle
85
+ * hooks can branch on what changed via `changedProperties`.
86
+ *
87
+ * For instance-local state, prefer a reactive property (`static
88
+ * properties = { foo: { state: true } }`) or a signal from
89
+ * `@webjsdev/core`'s `signal()`. The framework's built-in
90
+ * SignalWatcher wires every signal read in `render()` to a re-render
91
+ * automatically; explicit `requestUpdate()` is rarely needed.
92
+ */
93
+ requestUpdate(name?: string, oldValue?: unknown): void;
94
+ /** A Promise that resolves after the next render commit. */
95
+ readonly updateComplete: Promise<boolean>;
96
+ /** Override point for `updateComplete`. Default returns the internal promise. */
97
+ getUpdateComplete(): Promise<boolean>;
98
+ /** Attach a reactive controller. */
99
+ addController(controller: ReactiveController): void;
100
+ /** Detach a reactive controller. */
101
+ removeController(controller: ReactiveController): void;
102
+ /** Returns the template for this render. May be async. */
103
+ render(): TemplateResult | Promise<TemplateResult> | void;
104
+ /** Decide whether to update. Default returns `true`. */
105
+ shouldUpdate(changedProperties: Map<string, unknown>): boolean;
106
+ /** Pre-render hook. Safe to set properties; folds into current cycle. */
107
+ willUpdate(changedProperties: Map<string, unknown>): void;
108
+ /** Render-and-commit step. Default calls `render()` and commits. */
109
+ update(changedProperties: Map<string, unknown>): void;
110
+ /** Post-render hook. Runs after every commit. */
111
+ updated(changedProperties: Map<string, unknown>): void;
112
+ /** One-shot hook after the first render lands in the DOM. */
113
+ firstUpdated?(changedProperties: Map<string, unknown>): void;
114
+ /** Optional render-error boundary inside the component. */
115
+ renderError?(error: Error): TemplateResult | void;
116
+
117
+ connectedCallback?(): void;
118
+ disconnectedCallback?(): void;
119
+ attributeChangedCallback?(name: string, oldValue: string | null, newValue: string | null): void;
120
+ }