# @ivanlog/gs

Universal DOM/state runtime for GS-generated TypeScript browser applications.

Generated projects import `@ivanlog/gs` for typed DOM wrappers, template component instances, `gs-ctrl` controls, injected slots, forms, state routing and the common application model. GS 2.0 adds `AppBrowser`, universal states, layouts and typed adoption of server-rendered DOM. SSR is supplied by the companion `@ivanlog/gs-server` package.

## Install

```sh
npm install @ivanlog/gs
```

## TypeScript Usage

Generated GS code normally imports the package as a namespace:

```ts
import * as gs from "@ivanlog/gs";

const root = gs.w(document.querySelector("#app"));
const items = gs.q(".item");
```

The package exposes compiled JavaScript in `bin/**` and TypeScript declarations in `bin/**/*.d.ts`.

## External Browser Runtime

Browser artifacts are produced by esbuild during `npm run build:all` and `npm pack`, then published in `browser/**`. The generated folder is not repository source. New applications can keep GS outside their frequently changing application bundle by externalizing `@ivanlog/gs` and mapping it to the ESM browser entry:

```html
<script type="importmap">
{
  "imports": {
    "@ivanlog/gs": "/js/gs.min.js"
  }
}
</script>
<script type="module" src="/js/app.js"></script>
```

The project build copies the exported `@ivanlog/gs/browser` artifact from its pinned npm dependency to `/js/gs.min.js`. Production builds should give that file a content fingerprint or its immutable npm package version and serve it like the other static files under `htdocs`; npm and `node_modules` are not exposed at runtime.

The compatibility bundle remains available for applications that intentionally use a global API:

```html
<script src="./node_modules/@ivanlog/gs/browser/gs.min.js"></script>
```

That compatibility bundle registers its public API on `globalThis.gs`. The ESM `@ivanlog/gs/browser` artifact and the normal package entrypoint do not create a global variable.

An application that bundles npm modules but still needs the legacy global can opt into it explicitly:

```ts
import "@ivanlog/gs/browser-global";
```

## Browser and server applications

Projects define separate final classes over `AppBrowser` from this package and `AppServer` from `@ivanlog/gs-server`. Both use the same DI and explicit state registration model. Universal states can be registered in both; private or unported states remain browser-only.

The shared HTML shell should contain one `<main gs-app></main>` mounting root. Browser rendering and server composition use that same root selector.

The server runtime is a separate package so browser code and dependencies contain no SSR or Node implementation:

```ts
import { AppServer, serve } from "@ivanlog/gs-server";
```

It requires Node 18 or newer for native `fetch`, `Request` and `Response`.

GS SSR is anonymous-only. Private/authenticated states stay in the browser application; credential-bearing requests bypass the HTML cache and their authorization/cookie headers are not exposed to server state code.

The repository includes a GS 2.0 guide and runnable `example`, but this package README is intentionally self-contained.

## Main Runtime Areas

- `WrapperGS` - central DOM wrapper with cached instances, class/tag based wrapper extension, DOM operations, state helpers, `data-*` and `gs-*` helpers.
- `TemplateGS` - template lookup and component construction for generated `<template gs-tmpl="...">` fragments.
- `GS` - query wrapper used by `gs.q(selector)` for batch DOM operations.
- `App`, `AppBrowser` - compact application roots for DI, lifecycle and browser settings. `AppServer` belongs to `@ivanlog/gs-server`.
- `StateGS`, `StatePagedGS` - shared query/path routing and page-bearing state lifecycle.
- State head management - shared SSR/browser title, description, robots, canonical, Open Graph, alternate-link and JSON-LD reconciliation through `StateGS`.
- `LayoutGS`, `GuiBrowserGS` - reusable layouts, browser registration and access to active layout/page instances. Server composition remains internal.
- `EventsGS` - typed sync/async event helpers.
- `FormGS` - form value collection, filling and validation.
- `com/**` - wrappers for forms, inputs, files, textarea, select, option, anchor, label, dialog, details, progress, meter, image, toggles and box controls.
- `ctrls/**` - declarative, form-independent `gs-focus` keyboard navigation.
- `helpers/**` - browser helpers for HTML, arrays, dates, files, blobs, images, text, validation, localization, cookies, URLs and crypto utilities.

`gs.generators.createPassword()` creates a cryptographically secure 16-character password without visually ambiguous characters; `createHexString()` creates 32 lowercase hexadecimal characters by default. Both accept an explicit non-negative length and require `crypto.getRandomValues`.

`gs.localization` defaults to English, accepts arbitrary normalized language codes and provides `setLangAndReload(...)` for the full rebuild required by template-localized pages. Validation catalogs follow the active browser/server request language; English and Russian are included and applications can register complete additional catalogs.

## Generated Template Integration

GS template tooling generates TypeScript classes that expect this package:

```ts
import * as gs from "@ivanlog/gs";
```

At runtime, `WrapperGS` reads template metadata such as `gs-tmpl`, `gs-ctrl` and `gs-ins`, builds typed controls, and resolves injected components.

## Notes

- The main entry is universal/browser-safe; SSR and Node hosting are published as `@ivanlog/gs-server`.
- `globalThis.gs` is assigned only by the compatibility browser bundle or the explicit `@ivanlog/gs/browser-global` entrypoint. Importing the main package or the ESM browser runtime does not mutate the global object.
- ESM and compatibility browser artifacts are produced with esbuild.
- The package does not include the GS template generator CLI. That tool is distributed separately as `Ivanlog.GS.Templates.Tool`.
