Skip to content

Commit 49e2d6b

Browse files
committed
feat: rename core package webjs → @webjs/core for npm publish
The unscoped `webjs` name is already taken on npm (webjs@0.6.1, unrelated project). Moving to the `@webjs` scope lets us publish `@webjs/core`, `@webjs/server`, and `@webjs/cli` together. * Package name: `webjs` → `@webjs/core`. CLI binary stays `webjs`. * All imports migrated: `from 'webjs'` → `from '@webjs/core'`, subpaths `'webjs/client-router'` → `'@webjs/core/client-router'`, etc. * Import map + builtin set + dev server core resolver updated. * publishConfig.access = public, files whitelist, repository, homepage, bugs, license, keywords added to each published package. * README.md added for @webjs/core, @webjs/server, @webjs/cli. * Scaffolded template deps updated (webjs → @webjs/core). * Test symlinks updated (node_modules/webjs → node_modules/@webjs/core). * Docs, AGENTS.md, examples all rewritten to use the new specifier. * Lockfile regenerated. All 571 unit tests pass.
1 parent b82f444 commit 49e2d6b

116 files changed

Lines changed: 560 additions & 1188 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,12 @@ Every file is a plain ES module. No config required.
295295

296296
---
297297

298-
## Public API — `webjs`
298+
## Public API — `@webjs/core`
299299

300-
Import from the bare specifier `'webjs'` (resolved via the injected import map).
300+
Import from the bare specifier `'@webjs/core'` (resolved via the injected import map).
301301

302302
```js
303-
import { html, css, WebComponent, render, renderToString } from 'webjs';
303+
import { html, css, WebComponent, render, renderToString } from '@webjs/core';
304304
```
305305

306306
| Export | Purpose |
@@ -319,7 +319,7 @@ import { html, css, WebComponent, render, renderToString } from 'webjs';
319319
| `connectWS(url, handlers)` | Client-side WebSocket with auto-reconnect, JSON parse/stringify, queued sends. |
320320
| `richFetch<T>(url, init?)` | Client-side fetch that adds `Accept: application/vnd.webjs+json`, encodes plain-object bodies via superjson, and decodes responses with rich types. |
321321

322-
### Directives — `import { … } from 'webjs/directives'`
322+
### Directives — `import { … } from '@webjs/core/directives'`
323323

324324
webjs follows a **"less is more"** philosophy: only directives that solve
325325
problems with NO native alternative are included. AI agents don't need
@@ -349,7 +349,7 @@ syntax sugar — they write code that works, not code that looks pretty.
349349
| Async data in page | `async` page function (just `await`) |
350350
| Lists without reorder | `${items.map(item => html\`\`)}` |
351351

352-
### Context Protocol — `import { … } from 'webjs/context'`
352+
### Context Protocol — `import { … } from '@webjs/core/context'`
353353

354354
Share data across deeply nested components without prop drilling.
355355

@@ -362,7 +362,7 @@ Share data across deeply nested components without prop drilling.
362362

363363
**When to use Context (AI hint):** Use when data (theme, auth state, locale, config) must reach components many levels deep without threading it through every intermediate component's attributes. Do NOT use for data that changes on every render (use state for that) or for data that only one component needs (use a server action or prop).
364364

365-
### Task Controller — `import { Task, TaskStatus } from 'webjs/task'`
365+
### Task Controller — `import { Task, TaskStatus } from '@webjs/core/task'`
366366

367367
Manages async operations (fetch, compute) inside components with automatic loading/error states and AbortController.
368368

@@ -447,7 +447,7 @@ TypeScript's class-field initializer doesn't clobber the reactive
447447
accessor the framework installs via `Object.defineProperty`.
448448

449449
```ts
450-
import { WebComponent, html } from 'webjs';
450+
import { WebComponent, html } from '@webjs/core';
451451
452452
class StudentCard extends WebComponent {
453453
static properties = { student: { type: Object } }; // runtime: tracked + coerced
@@ -636,7 +636,7 @@ interpolate via `<style>${STYLES.text}</style>`. `ts-lit-plugin` /
636636
Example (page):
637637

638638
```ts
639-
import { html, css } from 'webjs';
639+
import { html, css } from '@webjs/core';
640640
641641
const STYLES = css`
642642
.page-dashboard {
@@ -738,7 +738,7 @@ Set `static shadow = true` when:
738738
739739
```js
740740
// app/error.ts — root error boundary
741-
import { html } from 'webjs';
741+
import { html } from '@webjs/core';
742742

743743
export default function ErrorPage({ error }: { error: Error }) {
744744
return html`
@@ -757,7 +757,7 @@ A `loading.js` file is the automatic Suspense boundary for its sibling page. The
757757
758758
```js
759759
// app/blog/loading.ts — shown while blog pages load
760-
import { html } from 'webjs';
760+
import { html } from '@webjs/core';
761761

762762
export default function Loading() {
763763
return html`
@@ -861,7 +861,7 @@ Supported files: `sitemap.js`, `robots.js`, `manifest.js`, `icon.js`, `apple-ico
861861
- On the server these modules are imported normally; you can freely use Prisma, `fs`, environment variables, etc.
862862
- **Expose as REST**: wrap any action with `expose('METHOD /path', fn)` to ALSO make it reachable at a stable REST URL. The same function body powers both callers:
863863
```js
864-
import { expose } from 'webjs';
864+
import { expose } from '@webjs/core';
865865
export const createPost = expose('POST /api/posts', async ({ title, body }) => { … });
866866
```
867867
When called over HTTP, the adapter merges `{ ...query, ...urlParams, ...jsonBody }` into a single object argument. This is the recommended way to surface a server action to external consumers — no `route.js` wrapper needed.
@@ -988,7 +988,7 @@ no client-side runtime, no diff from writing the classes by hand.
988988
Scaffold example (`app/_utils/ui.ts`):
989989
990990
```ts
991-
import { html } from 'webjs';
991+
import { html } from '@webjs/core';
992992
993993
/** `● label` kicker — small caps, accent colour, above headings. */
994994
export function rubric(label: string, mb: 'sm' | 'md' = 'md') {
@@ -1060,7 +1060,7 @@ the class-prefix rule documented in the Shadow-vs-Light DOM section.
10601060
10611061
```js
10621062
// app/about/page.js
1063-
import { html } from 'webjs';
1063+
import { html } from '@webjs/core';
10641064
export default function About() {
10651065
return html`<h1>About</h1><p>…</p>`;
10661066
}
@@ -1070,7 +1070,7 @@ export default function About() {
10701070
10711071
```js
10721072
// app/users/[id]/page.js
1073-
import { html } from 'webjs';
1073+
import { html } from '@webjs/core';
10741074
export default async function User({ params }) {
10751075
// use a server action to fetch; never import a DB client directly in a page
10761076
const user = await fetchUser(params.id);
@@ -1132,7 +1132,7 @@ if (!r.success) this.setState({ error: r.error });
11321132
11331133
```js
11341134
// components/hello-world.js
1135-
import { WebComponent, html } from 'webjs';
1135+
import { WebComponent, html } from '@webjs/core';
11361136
export class HelloWorld extends WebComponent {
11371137
render() { return html`<p>Hello!</p>`; }
11381138
}
@@ -1305,7 +1305,7 @@ export async function GET() {
13051305
13061306
```ts
13071307
// caller — client side
1308-
import { richFetch } from 'webjs';
1308+
import { richFetch } from '@webjs/core';
13091309
const posts = await richFetch<Post[]>('/api/posts');
13101310
// posts[0].createdAt is a Date here (richFetch sends
13111311
// Accept: application/vnd.webjs+json and superjson-parses the response).
@@ -1474,7 +1474,7 @@ and what stays in-memory.
14741474
### Streaming SSR / Suspense
14751475
14761476
```js
1477-
import { html, Suspense } from 'webjs';
1477+
import { html, Suspense } from '@webjs/core';
14781478

14791479
export default function Page() {
14801480
return html`
@@ -1580,7 +1580,7 @@ then segment-scoped files.
15801580
15811581
### Client router — Turbo Drive-style navigation
15821582
1583-
`import 'webjs/client-router'` enables SPA-style navigation without full page reloads. Intercepts same-origin `<a>` clicks (including inside shadow DOM via `composedPath()`), fetches the target HTML, and swaps DOM content.
1583+
`import '@webjs/core/client-router'` enables SPA-style navigation without full page reloads. Intercepts same-origin `<a>` clicks (including inside shadow DOM via `composedPath()`), fetches the target HTML, and swaps DOM content.
15841584
15851585
**How it works:**
15861586
1. Fetches the target URL's HTML via `fetch()`.
@@ -1592,7 +1592,7 @@ then segment-scoped files.
15921592
15931593
**Programmatic navigation:**
15941594
```js
1595-
import { navigate } from 'webjs/client-router';
1595+
import { navigate } from '@webjs/core/client-router';
15961596
await navigate('/about'); // push to history
15971597
await navigate('/login', { replace: true }); // replace history entry
15981598
```
@@ -1686,7 +1686,7 @@ Use `node:test` and `node:assert/strict`. Test server actions, components
16861686
```ts
16871687
import { test } from 'node:test';
16881688
import assert from 'node:assert/strict';
1689-
import { html, renderToString } from 'webjs';
1689+
import { html, renderToString } from '@webjs/core';
16901690
16911691
test('component renders heading', async () => {
16921692
const result = await renderToString(html`<h1>Hello</h1>`);

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ CLAUDE.md # Claude Code quick-reference
6868

6969
```ts
7070
// app/page.ts — server-rendered, async data fetching
71-
import { html, repeat } from 'webjs';
71+
import { html, repeat } from '@webjs/core';
7272
import '../components/counter.ts';
7373
import { listPosts } from '../modules/posts/queries/list-posts.server.ts';
7474

@@ -88,7 +88,7 @@ export default async function Home() {
8888

8989
```ts
9090
// components/counter.ts — interactive web component, light DOM + Tailwind
91-
import { WebComponent, html } from 'webjs';
91+
import { WebComponent, html } from '@webjs/core';
9292

9393
export class Counter extends WebComponent {
9494
// Light DOM is the default; Tailwind utility classes apply directly.

docs/app/docs/ai-first/page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'AI-First Development — webjs' };
44

docs/app/docs/api-routes/page.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'API Routes — webjs' };
44

@@ -133,7 +133,7 @@ export async function POST(req: Request) {
133133
134134
<h2>richFetch() -- Typed Client Calls</h2>
135135
<p>On the client side, <code>richFetch()</code> from <code>webjs</code> is a drop-in replacement for <code>fetch()</code> that enables the superjson round trip:</p>
136-
<pre>import { richFetch } from 'webjs';
136+
<pre>import { richFetch } from '@webjs/core';
137137
138138
// GET with rich types
139139
const posts = await richFetch('/api/posts');

docs/app/docs/architecture/page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'Architecture — webjs' };
44

docs/app/docs/auth/page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'Authentication — webjs' };
44

docs/app/docs/authentication/page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'Authentication — webjs' };
44

docs/app/docs/backend-only/page.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'Backend-Only Mode — webjs' };
44

@@ -129,7 +129,7 @@ export default rateLimit({ window: '10s', max: 5 });</pre>
129129
<p><code>expose()</code> turns a server action into a typed REST endpoint. This is especially useful in backend-only mode because it lets you define your API logic as plain functions with validation, then expose them over HTTP:</p>
130130
<pre>// actions/users.server.ts
131131
'use server';
132-
import { expose } from 'webjs';
132+
import { expose } from '@webjs/core';
133133
import { prisma } from '../lib/prisma.ts';
134134
135135
export const listUsers = expose('GET /api/v2/users', async () =&gt; {
@@ -197,7 +197,7 @@ export async function GET() {
197197
return json(events); // dates stay as Dates for richFetch callers
198198
}</pre>
199199
<pre>// Internal client (another webjs app or same-app component)
200-
import { richFetch } from 'webjs';
200+
import { richFetch } from '@webjs/core';
201201
202202
const events = await richFetch('/api/events');
203203
// events[0].createdAt is a real Date object
@@ -285,8 +285,8 @@ fastify.listen({ port: 3000 });</pre>
285285
},
286286
"dependencies": {
287287
"@webjs/cli": "0.1.0",
288+
"@webjs/core": "0.1.0",
288289
"@webjs/server": "0.1.0",
289-
"webjs": "0.1.0",
290290
"@prisma/client": "^6.0.0"
291291
},
292292
"devDependencies": {

docs/app/docs/cache/page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'Caching — webjs' };
44

docs/app/docs/client-router/page.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { html } from 'webjs';
1+
import { html } from '@webjs/core';
22

33
export const metadata = { title: 'Client Router — webjs' };
44

@@ -45,7 +45,7 @@ export default function ClientRouter() {
4545
<h2>Programmatic navigation</h2>
4646
<p>Use <code>navigate()</code> instead of <code>location.href = ...</code>:</p>
4747
48-
<pre>import { navigate } from 'webjs/client-router';
48+
<pre>import { navigate } from '@webjs/core/client-router';
4949
5050
// Normal navigation (adds to history)
5151
await navigate('/about');
@@ -54,7 +54,7 @@ await navigate('/about');
5454
await navigate('/login', { replace: true });</pre>
5555
5656
<h2>Disabling the router entirely</h2>
57-
<pre>import { disableClientRouter } from 'webjs/client-router';
57+
<pre>import { disableClientRouter } from '@webjs/core/client-router';
5858
disableClientRouter();</pre>
5959
6060
<h2>Listening for navigations</h2>

0 commit comments

Comments
 (0)