Skip to content

Commit 316e2be

Browse files
committed
feat: rescope @webjs → @webjskit (org name 'webjs' unavailable on npm)
The @webjs organization is not available on npm (likely reserved because the unscoped `webjs` package is held by an unrelated project). Switching to the @webjskit scope, which we own. No behaviour changes — just a scope rename across: * Package names: @webjs/core, @webjs/server, @webjs/cli, @webjs/docs, @webjs/website, @webjs-examples/blog → @webjskit/* / @webjskit-examples/* * All import specifiers ('@webjs/core' → '@webjskit/core', etc.) * Import map, BUILTIN set, core resolver in dev server * Test symlinks (node_modules/@webjs/core → node_modules/@webjskit/core) * Scaffolded template deps * Docs, READMEs, AGENTS.md * Lockfile regenerated All 571 unit tests still pass.
1 parent 49e2d6b commit 316e2be

135 files changed

Lines changed: 457 additions & 455 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: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ node_modules/
226226
router-client.js ← Turbo Drive–style client router
227227
suspense.js ← streaming Suspense boundary
228228
lazy-loader.js ← IntersectionObserver–based lazy module loading
229-
@webjs/server/ ← server: SSR, router, actions, dev server
229+
@webjskit/server/ ← server: SSR, router, actions, dev server
230230
src/
231231
dev.js ← request handler, file serving, TS transforms
232232
router.js ← file-based route scanner + matcher
@@ -236,7 +236,7 @@ node_modules/
236236
check.js ← convention validator (webjs check)
237237
vendor.js ← auto-bundle npm deps for browser
238238
module-graph.js ← dependency graph for transitive preloads
239-
@webjs/cli/ ← CLI: dev, start, build, test, check, create
239+
@webjskit/cli/ ← CLI: dev, start, build, test, check, create
240240
```
241241

242242
**AI agents: when debugging framework behaviour** (e.g., "why doesn't my
@@ -295,12 +295,12 @@ Every file is a plain ES module. No config required.
295295

296296
---
297297

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

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

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

306306
| Export | Purpose |
@@ -319,7 +319,7 @@ import { html, css, WebComponent, render, renderToString } from '@webjs/core';
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/core/directives'`
322+
### Directives — `import { … } from '@webjskit/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/core/context'`
352+
### Context Protocol — `import { … } from '@webjskit/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/core/task'`
365+
### Task Controller — `import { Task, TaskStatus } from '@webjskit/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/core';
450+
import { WebComponent, html } from '@webjskit/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/core';
639+
import { html, css } from '@webjskit/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/core';
741+
import { html } from '@webjskit/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/core';
760+
import { html } from '@webjskit/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/core';
864+
import { expose } from '@webjskit/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/core';
991+
import { html } from '@webjskit/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/core';
1063+
import { html } from '@webjskit/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/core';
1073+
import { html } from '@webjskit/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/core';
1135+
import { WebComponent, html } from '@webjskit/core';
11361136
export class HelloWorld extends WebComponent {
11371137
render() { return html`<p>Hello!</p>`; }
11381138
}
@@ -1183,7 +1183,7 @@ Reference it via JSDoc:
11831183
- Health probe: `GET /__webjs/health` and `/__webjs/ready` return `{status:"ok"}`
11841184
with `Cache-Control: no-store`. Wire these into your orchestrator.
11851185
- Embed in another runtime: import `createRequestHandler({ appDir, dev })`
1186-
from `@webjs/server`. It returns `{ handle(req: Request) → Promise<Response> }`
1186+
from `@webjskit/server`. It returns `{ handle(req: Request) → Promise<Response> }`
11871187
— usable in Express (`app.use((req, res) => …)`), Fastify, Deno, Bun, Workers.
11881188
- Plug your own logger via `createRequestHandler({ logger })`. Any `{ info,
11891189
warn, error }` shape works (pino, winston, etc.).
@@ -1295,7 +1295,7 @@ into rich types for your own UI code:
12951295
12961296
```ts
12971297
// app/api/posts/route.ts — server side
1298-
import { json } from '@webjs/server';
1298+
import { json } from '@webjskit/server';
12991299
import { listPosts } from '.../queries/list-posts.server.ts';
13001300

13011301
export async function GET() {
@@ -1305,7 +1305,7 @@ export async function GET() {
13051305
13061306
```ts
13071307
// caller — client side
1308-
import { richFetch } from '@webjs/core';
1308+
import { richFetch } from '@webjskit/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).
@@ -1319,7 +1319,7 @@ context:
13191319
- Otherwise → plain JSON with `Content-Type: application/json`.
13201320
13211321
Request bodies can be parsed with the dual-format `readBody(req)`
1322-
helper from `@webjs/server`.
1322+
helper from `@webjskit/server`.
13231323
13241324
### TypeScript is not required
13251325
@@ -1330,7 +1330,7 @@ Add `"checkJs": true` to `tsconfig.json` to enforce types in editor
13301330
+ CI. The framework doesn't care either way — pick what fits the
13311331
codebase.
13321332
1333-
## Built-in essentials — `import { … } from '@webjs/server'`
1333+
## Built-in essentials — `import { … } from '@webjskit/server'`
13341334
13351335
Opinionated defaults: **set `REDIS_URL` and everything scales.**
13361336
@@ -1362,23 +1362,23 @@ For app-level caching (database query results, expensive computations),
13621362
use the cache store directly:
13631363
13641364
```js
1365-
import { getStore } from '@webjs/server';
1365+
import { getStore } from '@webjskit/server';
13661366
const store = getStore(); // memory by default
13671367

13681368
// For Redis: configure explicitly at app startup
1369-
import { setStore, redisStore } from '@webjs/server';
1369+
import { setStore, redisStore } from '@webjskit/server';
13701370
setStore(redisStore({ url: process.env.REDIS_URL }));
13711371
```
13721372
13731373
### Sessions
13741374
13751375
```js
13761376
// middleware.js — add session support to all routes
1377-
import { session } from '@webjs/server';
1377+
import { session } from '@webjskit/server';
13781378
export default session(); // auto: REDIS_URL → server-side, otherwise → cookie
13791379

13801380
// In any page or action:
1381-
import { getSession } from '@webjs/server';
1381+
import { getSession } from '@webjskit/server';
13821382
const s = getSession(req);
13831383
s.userId = user.id; // auto-saved after response
13841384
```
@@ -1391,7 +1391,7 @@ Requires `SESSION_SECRET` environment variable.
13911391
13921392
```js
13931393
// lib/auth.ts — create once
1394-
import { createAuth, Credentials, Google, GitHub } from '@webjs/server';
1394+
import { createAuth, Credentials, Google, GitHub } from '@webjskit/server';
13951395

13961396
export const { auth, signIn, signOut, handlers } = createAuth({
13971397
providers: [
@@ -1431,7 +1431,7 @@ providers (Google, GitHub) handle the full redirect flow.
14311431
14321432
```js
14331433
// app/api/chat/route.ts
1434-
import { broadcast } from '@webjs/server';
1434+
import { broadcast } from '@webjskit/server';
14351435

14361436
export function WS(ws, req) {
14371437
ws.on('message', (data) => {
@@ -1459,7 +1459,7 @@ scaling, the user explicitly configures Redis where needed:
14591459
14601460
```js
14611461
// app startup — explicit, no magic
1462-
import { setStore, redisStore } from '@webjs/server';
1462+
import { setStore, redisStore } from '@webjskit/server';
14631463
setStore(redisStore({ url: process.env.REDIS_URL }));
14641464
// Now rate limiter and sessions share state across instances
14651465
```
@@ -1474,7 +1474,7 @@ and what stays in-memory.
14741474
### Streaming SSR / Suspense
14751475
14761476
```js
1477-
import { html, Suspense } from '@webjs/core';
1477+
import { html, Suspense } from '@webjskit/core';
14781478

14791479
export default function Page() {
14801480
return html`
@@ -1548,15 +1548,15 @@ Fixed-window limiter shaped as middleware. Place it in `middleware.ts` at whatev
15481548
15491549
```js
15501550
// app/api/auth/middleware.ts — protect login/signup from brute force
1551-
import { rateLimit } from '@webjs/server';
1551+
import { rateLimit } from '@webjskit/server';
15521552
export default rateLimit({ window: '10s', max: 5 });
15531553

15541554
// app/api/middleware.ts — general API rate limit
1555-
import { rateLimit } from '@webjs/server';
1555+
import { rateLimit } from '@webjskit/server';
15561556
export default rateLimit({ window: '1m', max: 60 });
15571557

15581558
// Custom key: rate limit per authenticated user instead of IP
1559-
import { rateLimit } from '@webjs/server';
1559+
import { rateLimit } from '@webjskit/server';
15601560
export default rateLimit({
15611561
window: '1m', max: 30,
15621562
key: async (req) => {
@@ -1580,7 +1580,7 @@ then segment-scoped files.
15801580
15811581
### Client router — Turbo Drive-style navigation
15821582
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.
1583+
`import '@webjskit/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/core/client-router';
1595+
import { navigate } from '@webjskit/core/client-router';
15961596
await navigate('/about'); // push to history
15971597
await navigate('/login', { replace: true }); // replace history entry
15981598
```
@@ -1637,7 +1637,7 @@ Import `createRequestHandler` and adapt the platform's Request/Response:
16371637
```js
16381638
// Express
16391639
import express from 'express';
1640-
import { createRequestHandler } from '@webjs/server';
1640+
import { createRequestHandler } from '@webjskit/server';
16411641
const webjs = await createRequestHandler({ appDir });
16421642
app.use(async (req, res) => {
16431643
const webReq = new Request(`http://${req.headers.host}${req.url}`, {
@@ -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/core';
1689+
import { html, renderToString } from '@webjskit/core';
16901690
16911691
test('component renders heading', async () => {
16921692
const result = await renderToString(html`<h1>Hello</h1>`);

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ cd website && npm run dev # just the website
5555
```
5656
packages/
5757
core/ # webjs — html, css, WebComponent, renderers, client router
58-
server/ # @webjs/server — dev/prod server, router, SSR, actions, WS
59-
cli/ # @webjs/cli — webjs dev/start/build/db
58+
server/ # @webjskit/server — dev/prod server, router, SSR, actions, WS
59+
cli/ # @webjskit/cli — webjs dev/start/build/db
6060
examples/
6161
blog/ # full-featured reference app (auth, posts, comments, chat)
6262
docs/ # documentation site (built on webjs itself)
@@ -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/core';
71+
import { html, repeat } from '@webjskit/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/core';
91+
import { WebComponent, html } from '@webjskit/core';
9292

9393
export class Counter extends WebComponent {
9494
// Light DOM is the default; Tailwind utility classes apply directly.
@@ -134,7 +134,7 @@ Health: `GET /__webjs/health`. Graceful shutdown on `SIGTERM`.
134134
Embed in Express/Fastify/Bun/Deno:
135135

136136
```ts
137-
import { createRequestHandler } from '@webjs/server';
137+
import { createRequestHandler } from '@webjskit/server';
138138
const app = await createRequestHandler({ appDir: process.cwd() });
139139
const resp = await app.handle(new Request('http://x/api/hello'));
140140
```

docs/app/docs/ai-first/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/core';
1+
import { html } from '@webjskit/core';
22

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

@@ -24,7 +24,7 @@ export default function AIFirst() {
2424
<p>Every webjs app has an <code>AGENTS.md</code> at the root. This is a structured document that AI agents read before touching any code. It contains:</p>
2525
<ul>
2626
<li><strong>File conventions table</strong> — which filename means what (page.ts, route.ts, middleware.ts, .server.ts, etc.).</li>
27-
<li><strong>Public API surface</strong> — every exported function from <code>webjs</code> and <code>@webjs/server</code> with a one-line description.</li>
27+
<li><strong>Public API surface</strong> — every exported function from <code>webjs</code> and <code>@webjskit/server</code> with a one-line description.</li>
2828
<li><strong>Invariants</strong> — rules that must never be broken ("never import @prisma/client from a component", "event holes must be unquoted").</li>
2929
<li><strong>Recipes</strong> — step-by-step instructions for "add a page", "add a server action", "add a component", "add a DB model".</li>
3030
<li><strong>What's deliberately deferred</strong> — so agents don't try to implement features that aren't supported yet.</li>
@@ -142,7 +142,7 @@ Autonomous mode ✅ defaults ❌ n/a ❌ n/a</pre>
142142
<pre>## What webjs is
143143
## App layout (file conventions table)
144144
## Public API — webjs
145-
## Public API — @webjs/server
145+
## Public API — @webjskit/server
146146
## Modules architecture
147147
## File conventions — detail (pages, layouts, routes, actions, components)
148148
## Invariants (rules agents must follow)

0 commit comments

Comments
 (0)