@temir.ra/create-ts-lib 0.2.2 → 0.2.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Version 0
2
2
 
3
+ ## 0.2.4
4
+
5
+ 1. Documented template caching in the Quick Start section with commands to pin the version or clear the cache.
6
+ 2. Minor README updates: Revised Asset Resolution sections in root and template; Added introductory paragraph to Documentation section;
7
+ 3. Moved git-upstream to `https://git.chimps.quest/trs/create-ts-lib.git`.
8
+
9
+ ## 0.2.3
10
+
11
+ 1. Updated change management workflow in `README.md` and `template/README.md`: build step now happens after merge (not before PR), so `buildinfo.txt` captures the correct git hash and artifacts are up to date before publish.
12
+ 2. Added Change Management section to root and template `CLAUDE.md`.
13
+
3
14
  ## 0.2.2
4
15
 
5
16
  1. Fixed `CHANGELOG.md` and `buildinfo.txt` copy paths in `cli.ts`: they were resolved relative to `template/` instead of the package root, causing the copy to fail. Refactored URL/path construction to derive all paths from a single `packageUrl`, eliminating redundant `fileURLToPath` calls at each copy site.
package/README.md CHANGED
@@ -11,9 +11,17 @@ A template for TypeScript libraries distributed via npm-compatible registries. P
11
11
  3. [Script `scripts/buildinfo.ts`](#script-scriptsbuildinfots)
12
12
  4. [Script `scripts/build-lib-bundle.ts`](#script-scriptsbuild-lib-bundlets)
13
13
  5. [CDN Map `scripts/cdn-rewrite-map.json`](#cdn-map-scriptscdn-rewrite-mapjson)
14
- 6. [Asset Resolution](#asset-resolution)
15
- 7. [`src/dev.ts`](#srcdevts)
16
- 8. [`CLAUDE.md` / `AGENTS.md`](#claudemd--agentsmd)
14
+ 6. [`"bin"` field in `package.json`](#bin-field-in-packagejson)
15
+ 7. [Asset Resolution](#asset-resolution)
16
+ 1. [Externalized - loaded from CDN or `node_modules/`](#externalized---loaded-from-cdn-or-node_modules)
17
+ 2. [Bundled - absorbed into the consumer's output](#bundled---absorbed-into-the-consumers-output)
18
+ 3. [Contract](#contract)
19
+ 1. [Scoped assets directory convention](#scoped-assets-directory-convention)
20
+ 2. [Accessing assets](#accessing-assets)
21
+ 3. [README statement for library consumers](#readme-statement-for-library-consumers)
22
+ 4. [When the library is bundled by the consumer](#when-the-library-is-bundled-by-the-consumer)
23
+ 8. [`src/dev.ts`](#srcdevts)
24
+ 9. [`CLAUDE.md` / `AGENTS.md`](#claudemd--agentsmd)
17
25
  3. [DevOps](#devops)
18
26
  1. [Build](#build)
19
27
  2. [Change Management](#change-management)
@@ -23,17 +31,34 @@ A template for TypeScript libraries distributed via npm-compatible registries. P
23
31
 
24
32
  # Quick Start
25
33
 
34
+ *`bun create` caches the template package - a newer published version will not be picked up automatically. Pin the version or clear the cache to use the latest.*
35
+
26
36
  ```bash
27
37
  # placeholder:
28
- # <PACKAGE: <PACKAGE>
38
+ # <NEW_PACKAGE: <NEW_PACKAGE>
39
+ # <@_VERSION: <@_VERSION>
40
+
41
+ # identify the latest version of the template package as <@_VERSION.
42
+ bun info "@temir.ra/create-ts-lib" version
43
+ # create a new library from the template version
44
+ bun create --no-install --no-git "@temir.ra/ts-lib<@_VERSION>" <NEW_PACKAGE>
45
+
46
+ # or
47
+
48
+ # clear package manager cache to ensure the latest template version is used
49
+ bun pm cache rm
50
+ # create a new library from the latest template version
51
+ bun create --no-install --no-git "@temir.ra/ts-lib" <NEW_PACKAGE>
29
52
 
30
- bun create --no-install --no-git "@temir.ra/ts-lib" <PACKAGE>
31
- cd <PACKAGE>
53
+ # dependencies must be installed manually
54
+ cd <NEW_PACKAGE>
32
55
  bun install
33
56
  ```
34
57
 
35
58
  # Documentation
36
59
 
60
+ The following sections explain the configurations and conventions baked into the generated package. Useful when adapting the template to fit a specific library's needs.
61
+
37
62
  ## `tsconfig.json` and `tsconfig.build.json`
38
63
 
39
64
  ```json
@@ -286,25 +311,42 @@ For CLI packages, add the following to `package.json`:
286
311
 
287
312
  ## Asset Resolution
288
313
 
289
- The key question to ask is: **does my library retain its own URL at runtime?** Module identity is the invariant. Everything else follows from it.
314
+ The key question to ask is: **does my library retain its own URL at runtime?** Everything else follows from it.
290
315
 
291
- ### Externalized - loaded from CDN or node_modules
316
+ ### Externalized - loaded from CDN or `node_modules/`
292
317
 
293
318
  The consumer does not bundle the library. It is loaded as a discrete module at runtime. Module identity is preserved regardless of the URL form:
294
319
 
295
320
  ```
296
- https://cdn.jsdelivr.net/npm/@scope/lib@1.0.0/dist/index.js
297
- file:///project/node_modules/@scope/lib/dist/index.js
298
- https://your-own-cdn.com/lib/index.js
321
+ https://cdn.jsdelivr.net/npm/@scope/lib-name@1.0.0/dist/index.js
322
+ file:///project/node_modules/@scope/lib-name/dist/index.js
323
+ https://your-own-cdn.com/lib-name/index.js
299
324
  ```
300
325
 
301
- `import.meta.url` is reliable in all these cases. Asset paths resolve automatically - the consumer does nothing. `fetch()` is the correct I/O mechanism because it accepts both `https://` and `file://` URLs, making it universally correct for isomorphic (browser + Node) libraries.
326
+ `import.meta.url` is reliable in all these cases. `fetch()` is the correct I/O mechanism because it accepts both `https://` and `file://` URLs, making it universally correct for isomorphic (`--target node` or `--target browser`) libraries.
327
+
328
+ ### Bundled - absorbed into the consumer's output
329
+
330
+ The consumer's bundler absorbs the library into their own output. Module identity is destroyed - `import.meta.url` now points to the consumer's bundle, not the library's. However, **the path relationship can be preserved by convention**: if the consumer copies the library's assets into their build output at the same relative path the library expects, `import.meta.url` resolution continues to work correctly.
331
+
332
+ ### Contract
333
+
334
+ If the library has runtime assets, the following contract applies:
302
335
 
303
- ### Bundled into the consumer's app
336
+ **The library must:**
337
+ 1. **Place assets in a scoped assets directory** - see [Scoped assets directory convention](#scoped-assets-directory-convention) below.
338
+ 2. **Access assets via `import.meta.url`** - see [Accessing assets](#accessing-assets) below.
339
+ 3. **Document the bundled case** - see [README statement for library consumers](#readme-statement-for-library-consumers) below.
304
340
 
305
- The consumer's bundler absorbs the library into their own output file. Module identity is destroyed - `import.meta.url` now points to the consumer's bundle, not the library's file. However, **the path relationship can be preserved by convention**: if the consumer copies the library's assets into their build output at the same relative path the library expects, `import.meta.url` resolution continues to work correctly.
341
+ **The consumer must,**
342
+ - **when loading the library externalized:** do nothing - the library's `import.meta.url` works as-is, and assets load from their original location (CDN or `node_modules/`).
343
+ - **when bundling the library:**
344
+ 1. **Copy the assets** - see [When the library is bundled by the consumer](#when-the-library-is-bundled-by-the-consumer) below.
345
+ 2. **Ensure the assets are served**
346
+ - if the consumer is a web server, ensure the copied assets are served as static files
347
+ - if the consumer is a bundler, ensure the copied assets are included in the bundle output
306
348
 
307
- ### Scoped asset folder convention
349
+ #### Scoped assets directory convention
308
350
 
309
351
  Place all runtime assets under a scoped directory that mirrors the package name:
310
352
 
@@ -312,13 +354,12 @@ Place all runtime assets under a scoped directory that mirrors the package name:
312
354
  assets/
313
355
  └── @scope/
314
356
  └── lib-name/
315
- ├── schema.json
316
- └── data.json
357
+ └── <ASSETS>
317
358
  ```
318
359
 
319
360
  This prevents naming collisions when multiple libraries are bundled into the same consumer app. Each library's assets live under their own namespace; no library can shadow another's files.
320
361
 
321
- Add `assets/` to the `files` field in `package.json` so npm publishes it:
362
+ Add `assets/` to the `files` field in `package.json` so that the assets are included in the published package:
322
363
 
323
364
  ```json
324
365
  "files": [
@@ -329,93 +370,50 @@ Add `assets/` to the `files` field in `package.json` so npm publishes it:
329
370
  ],
330
371
  ```
331
372
 
332
- ### Accessing assets
373
+ #### Accessing assets
333
374
 
334
- Construct asset URLs directly from `import.meta.url`. Replace `@scope/lib-name` with your actual package name:
375
+ Construct asset URLs directly from `import.meta.url`.
335
376
 
336
377
  ```typescript
337
378
  const packageUrl = new URL('../', import.meta.url);
338
379
  const assetsUrl = new URL('assets/@scope/lib-name/', packageUrl);
339
380
 
340
- // isomorphic (browser or Node) - fetch accepts both https:// and file:// URLs
341
- const schema = await fetch(new URL('schema.json', assetsUrl)).then(r => r.json());
381
+ // for --target browser
382
+ const asset = await fetch(new URL('<ASSET>', assetsUrl)).then(r => r.json());
342
383
 
343
- // server-only (Node/Bun)
384
+ // for --target node
344
385
  import { readFile } from 'node:fs/promises';
345
386
  import { fileURLToPath } from 'url';
346
- const data = JSON.parse(await readFile(fileURLToPath(new URL('data.json', assetsUrl)), 'utf-8'));
387
+ const asset = JSON.parse(await readFile(fileURLToPath(new URL('<ASSET>', assetsUrl)), 'utf-8'));
347
388
  ```
348
389
 
349
- `fetch()` is the correct I/O primitive for isomorphic libraries: it accepts both `https://` URLs (CDN/production) and `file://` URLs (node_modules/development) without any special handling.
390
+ ### README statement for library consumers
391
+
392
+ ```markdown
393
+ <!-- placeholder:
394
+ <SCOPE: <SCOPE>
395
+ <LIB_NAME: <LIB_NAME>
396
+ -->
350
397
 
351
- > **Server-only libraries** (no browser target, bundled-into-consumer scenario unlikely): use `readFile` directly - `fetch()` is not required. The scoped asset convention still applies unchanged.
398
+ ## Asset resolution
352
399
 
353
- ### When the library is bundled by the consumer
400
+ This library resolves assets at runtime using `import.meta.url`. If you bundle this library into your application, copy `node_modules/<SCOPE>/<LIB_NAME>/assets/<SCOPE>/<LIB_NAME>/` into your build output directory alongside your bundle.
401
+ ```
402
+
403
+ #### When the library is bundled by the consumer
354
404
 
355
405
  The consumer must copy the assets into their build output at the same relative path the library expects:
356
406
 
357
407
  ```
358
408
  consumer output/
359
- ├── bundle.js ← import.meta.url points here
409
+ ├── bundle.js ← import.meta.url points here
360
410
  └── assets/
361
411
  └── @scope/
362
412
  └── lib-name/
363
- ├── schema.json ← copied; relative path preserved
364
- └── data.json
413
+ └── <ASSETS> ← copied; relative path preserved
365
414
  ```
366
415
 
367
- From the bundle's perspective `assets/@scope/lib-name/` is at the same directory level as `bundle.js`, so `new URL('assets/@scope/lib-name/schema.json', import.meta.url)` resolves correctly. No code configuration is needed - only the file copy.
368
-
369
- ### Setup
370
-
371
- If your library has runtime assets, the steps to wire everything up:
372
-
373
- 1. **Create the scoped directory** `assets/@scope/lib-name/` and place asset files inside (replace `@scope/lib-name` with your actual package name).
374
-
375
- 2. **Access assets via `import.meta.url`** - see [Accessing assets](#accessing-assets) above.
376
-
377
- 3. **Publish the assets** - add `assets/` to the `files` field in `package.json`:
378
- ```json
379
- "files": [
380
- "dist",
381
- "CHANGELOG.md",
382
- "buildinfo.txt",
383
- "assets"
384
- ],
385
- ```
386
-
387
- 4. **Document the bundled case** - copy the [README statement](#readme-statement-for-your-consumers) into your library's README.
388
-
389
- ### Contract
390
-
391
- **The library must:**
392
- - Place assets under `assets/@scope/lib-name/` (mirroring the package name)
393
- - Resolve asset paths via `import.meta.url` - no shared helper file required
394
- - Include `assets/` in `package.json` `files`
395
- - Document the bundled-case copy requirement in its README
396
-
397
- **The consumer must, when bundling the library:**
398
- - Copy `node_modules/@scope/lib-name/assets/` into their build output alongside the bundle
399
- - Ensure assets are served
400
-
401
- **The consumer must do nothing when loading the library externalized.** Asset resolution is automatic.
402
-
403
- ### Checklist
404
-
405
- - [ ] Assets live under `assets/@scope/lib-name/` (matching the package name)
406
- - [ ] `assets/` is listed in `package.json` `files`
407
- - [ ] All asset access resolves paths via `import.meta.url` - no hardcoded paths
408
- - [ ] Library README documents the bundled-case copy requirement (see statement below)
409
-
410
- ### README statement for your consumers
411
-
412
- Copy this into your library's README:
413
-
414
- > **Asset resolution**
415
- >
416
- > This library resolves assets at runtime using `import.meta.url`. It works automatically when the library is loaded as an external module (from CDN or node_modules).
417
- >
418
- > If you bundle this library into your application, copy `node_modules/@scope/lib-name/assets/@scope/lib-name/` into your build output directory alongside your bundle. No code configuration is required.
416
+ From the bundle's perspective `assets/@scope/lib-name/` is at the same directory level as `bundle.js`, so `new URL('assets/@scope/lib-name/<ASSETS>', import.meta.url)` resolves correctly. No code configuration is needed - only the file copy.
419
417
 
420
418
  ## `src/dev.ts`
421
419
 
@@ -453,8 +451,9 @@ bun run dist/cli.bundle.js -- example
453
451
  2. Make the changes and commit.
454
452
  3. Bump the version in [`package.json`](package.json).
455
453
  4. Add an entry for the new version in [`CHANGELOG.md`](CHANGELOG.md).
456
- 5. Run `bun run build`.
457
- 6. Pull request the branch and publish.
454
+ 5. Pull request the branch.
455
+ 6. After merge, run `bun run build`.
456
+ 7. Publish
458
457
 
459
458
  ## Publish
460
459
 
package/buildinfo.txt CHANGED
@@ -1 +1 @@
1
- 0.2.2+77ce44b
1
+ 0.2.3+0a2de3a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temir.ra/create-ts-lib",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Typescript library template",
5
5
  "author": "temir.ra",
6
6
  "license": "MIT",
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "https://git.temirs.cloud/trs/create-ts-lib.git"
15
+ "url": "https://git.chimps.quest/trs/create-ts-lib.git"
16
16
  },
17
17
  "type": "module",
18
18
  "sideEffects": false,
@@ -77,30 +77,78 @@ import { Foo } from "./foo.js" // ✗ — if Foo is only used as a ty
77
77
 
78
78
  ### Asset Resolution (if the library has runtime assets)
79
79
 
80
- Place runtime assets (JSON data, WASM, binary files, etc.) under a scoped directory that mirrors the package name — this prevents naming collisions when multiple libraries are bundled into the same consumer app:
80
+ The key question: **does your library retain its own URL at runtime?** Everything else follows from it.
81
+
82
+ - **Externalized** (loaded from CDN or `node_modules/`): `import.meta.url` is reliable as-is — no consumer action needed.
83
+ - **Bundled** (absorbed into the consumer's output): `import.meta.url` points to the consumer's bundle, not the library's file. The path relationship can be preserved by convention — if the consumer copies the library's assets into their build output at the same relative path, resolution continues to work correctly.
84
+
85
+ #### Contract
86
+
87
+ **The library must:**
88
+ 1. Place assets in a scoped directory — `assets/@scope/lib-name/` (mirrors the package name, prevents collisions when multiple libraries share a consumer bundle).
89
+ 2. Access assets via `import.meta.url` — see code below.
90
+ 3. Document the bundled case in the library's README — see [README statement](#readme-statement-for-consumers) below.
91
+
92
+ **The consumer must,**
93
+ - **when loading the library externalized:** do nothing.
94
+ - **when bundling the library:** copy `node_modules/@scope/lib-name/assets/` into their build output alongside the bundle, and ensure the assets are served.
95
+
96
+ #### Scoped assets directory
81
97
 
82
98
  ```
83
- assets/@scope/lib-name/
84
- ├── data.json
85
- └── model.wasm
99
+ assets/
100
+ └── @scope/
101
+ └── lib-name/
102
+ └── <ASSETS>
86
103
  ```
87
104
 
105
+ Add `assets/` to `files` in `package.json` so it is included in the published package:
106
+
107
+ ```json
108
+ "files": ["dist", "CHANGELOG.md", "buildinfo.txt", "assets"]
109
+ ```
110
+
111
+ #### Accessing assets
112
+
88
113
  Resolve asset URLs inline from `import.meta.url` — no shared helper file:
89
114
 
90
115
  ```typescript
91
116
  const packageUrl = new URL('../', import.meta.url);
92
117
  const assetsUrl = new URL('assets/@scope/lib-name/', packageUrl);
93
118
 
94
- // isomorphic (browser + Node) — fetch() handles both https:// and file:// URLs
119
+ // for --target browser
95
120
  const data = await fetch(new URL('data.json', assetsUrl)).then(r => r.json());
96
121
 
97
- // server-only (Node/Bun)
122
+ // for --target node
98
123
  import { readFile } from 'node:fs/promises';
99
124
  import { fileURLToPath } from 'url';
100
125
  const raw = await readFile(fileURLToPath(new URL('data.json', assetsUrl)), 'utf-8');
101
126
  ```
102
127
 
103
- Add `assets/` to `files` in `package.json` so it is included in the published package. See the [create-ts-lib README](../README.md) Asset Resolution section for the full setup guide, checklist, and the README statement to copy for your consumers.
128
+ #### When the library is bundled by the consumer
129
+
130
+ The consumer must copy assets into their build output at the same relative path:
131
+
132
+ ```
133
+ consumer output/
134
+ ├── bundle.js ← import.meta.url points here
135
+ └── assets/
136
+ └── @scope/
137
+ └── lib-name/
138
+ └── <ASSETS> ← copied; relative path preserved
139
+ ```
140
+
141
+ No code configuration needed — only the file copy.
142
+
143
+ #### README statement for consumers
144
+
145
+ Copy the following into the library's README (replace `<SCOPE>` and `<LIB_NAME>`):
146
+
147
+ ```markdown
148
+ ## Asset resolution
149
+
150
+ This library resolves assets at runtime using `import.meta.url`. If you bundle this library into your application, copy `node_modules/<SCOPE>/<LIB_NAME>/assets/<SCOPE>/<LIB_NAME>/` into your build output directory alongside your bundle.
151
+ ```
104
152
 
105
153
  ### Tests
106
154
 
@@ -153,6 +201,16 @@ Key `package.json` fields:
153
201
  - `"sideEffects": false` — enables full tree-shaking by bundlers
154
202
  - `"imports": { "#src/*.js": "./src/*.ts" }` — package-internal alias for `src/`; use as `import { foo } from "#src/module.js"`. **Only for `dev.ts`, `tests/`, and `scripts/`** — not for library source files compiled by `tsconfig.build.json`, as tsc emits the specifier verbatim and it would break in published unbundled output.
155
203
 
204
+ ## Change Management
205
+
206
+ 1. Branch off main.
207
+ 2. Make the changes and commit.
208
+ 3. Bump the version in [`package.json`](package.json).
209
+ 4. Add an entry for the new version in [`CHANGELOG.md`](CHANGELOG.md).
210
+ 5. Pull request the branch.
211
+ 6. After merge, run `bun run build`. ← must happen after merge so `buildinfo.txt` captures the correct git hash, and before publish so the artifacts are up to date.
212
+ 7. Publish.
213
+
156
214
  ## Publishing
157
215
 
158
216
  See [README.md](README.md) for registry setup and publish commands.
@@ -36,10 +36,20 @@ bun run dev
36
36
 
37
37
  # Documentation
38
38
 
39
- > If this library has runtime assets, see the **Asset Resolution** section in the create-ts-lib README for the setup guide, code examples, checklist, and consumer README statement.
40
-
41
39
  *&lt;DOCUMENTATION&gt;*
42
40
 
41
+ ## Asset Resolution
42
+
43
+ *&lt;!-- Remove this section if the library has no runtime assets. Replace `@scope/lib-name` throughout with the actual package name. --&gt;*
44
+
45
+ Assets are placed under `assets/@scope/lib-name/` (scoped to the package name to prevent collisions). They are resolved at runtime via `import.meta.url` and loaded with `fetch()` (browser) or `readFile` (Node). `assets/` must be listed in `files` in `package.json`.
46
+
47
+ `import.meta.url` is reliable when the library is loaded as a discrete module (from CDN or `node_modules/`). When the consumer bundles the library, they must copy the assets — see below.
48
+
49
+ ### For consumers bundling this library
50
+
51
+ Copy `node_modules/@scope/lib-name/assets/` into your build output alongside the bundle, preserving the relative path. No code configuration is required — only the file copy.
52
+
43
53
  # DevOps
44
54
 
45
55
  ## Change Management
@@ -48,8 +58,9 @@ bun run dev
48
58
  2. Make the changes and commit.
49
59
  3. Bump the version in [`package.json`](package.json).
50
60
  4. Add an entry for the new version in [`CHANGELOG.md`](CHANGELOG.md).
51
- 5. Run `bun run build`.
52
- 6. Pull request the branch and publish.
61
+ 5. Pull request the branch.
62
+ 6. After merge, run `bun run build`.
63
+ 7. Publish
53
64
 
54
65
  ## Publish
55
66