@weasel-js/icons 1.10.1 → 1.11.0

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/names.ts","../src/variants.ts","../src/registry.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { QualifiedIconName } from './index';\n\ndeclare const brand: unique symbol;\n\n/** A qualified icon name (`namespace:name`) that came from `icon()` or `toIconRef`. */\nexport type IconRef = string & { readonly [brand]: 'IconRef' };\n\nconst QUALIFIED = /^([^:\\s]+):([^:\\s]+)$/;\n\n/** `name` in `namespace`, unless it already names one. */\nexport function qualify(namespace: string, name: string): string {\n return name.includes(':') ? name : `${namespace}:${name}`;\n}\n\n/** The two halves of a qualified ref, or `undefined` for anything else. */\nexport function splitIconRef(ref: string): { namespace: string; name: string } | undefined {\n const m = QUALIFIED.exec(ref);\n return m ? { namespace: m[1]!, name: m[2]! } : undefined;\n}\n\n/** A string read at run time (a schema loaded as JSON) as a ref, when it is qualified. */\nexport function toIconRef(value: string | undefined): IconRef | undefined {\n return value !== undefined && QUALIFIED.test(value) ? (value as IconRef) : undefined;\n}\n\n/** A package's `icon()`: bare names resolve in `namespace` only. Generated into each package's `icons.gen.ts`. */\nexport function scopedIcon<Own extends string>(namespace: string) {\n return (name: Own | QualifiedIconName): IconRef => qualify(namespace, name) as IconRef;\n}\n","import { isDev } from '@weasel-js/registry';\nimport type { IconTable, IconVariantLoader } from './table';\n\n/** Where a named icon variant stands: no loader for it (`unknown`), a loader not yet run (`idle`), in flight, in, or failed. */\nexport type IconVariantState = 'unknown' | 'idle' | 'loading' | 'loaded' | 'failed';\n\n/** Loads each named variant at most once at a time; a failure leaves it retryable. */\nexport function createVariants(addTables: (tables: readonly IconTable[]) => void, changed: () => void) {\n const loaders = new Map<string, IconVariantLoader>();\n const states = new Map<string, IconVariantState>();\n const pending = new Map<string, Promise<void>>();\n\n const set = (name: string, state: IconVariantState) => {\n states.set(name, state);\n changed();\n };\n\n return {\n provide(next: Readonly<Record<string, IconVariantLoader>>): void {\n for (const [name, loader] of Object.entries(next)) {\n loaders.set(name, loader);\n if (!states.has(name)) states.set(name, 'idle');\n }\n changed();\n },\n state(name: string): IconVariantState {\n return states.get(name) ?? 'unknown';\n },\n load(name: string): Promise<void> {\n const loader = loaders.get(name);\n if (!loader || states.get(name) === 'loaded') return Promise.resolve();\n const inFlight = pending.get(name);\n if (inFlight) return inFlight;\n set(name, 'loading');\n const run = Promise.resolve()\n .then(loader)\n .then((mod) => {\n addTables(mod.default);\n set(name, 'loaded');\n })\n .catch((error: unknown) => {\n if (isDev()) console.error(`icon variant \"${name}\" failed to load`, error);\n set(name, 'failed');\n })\n .finally(() => pending.delete(name));\n pending.set(name, run);\n return run;\n },\n };\n}\n","import { createEmitter } from '@weasel-js/registry';\nimport type { IconRef } from './names';\nimport type { IconGlyph, IconTable, IconVariantLoader } from './table';\nimport { createVariants, type IconVariantState } from './variants';\n\nexport type { IconVariantState } from './variants';\n\n/** One icon as the registry reports it. */\nexport interface IconEntry {\n readonly ref: IconRef;\n readonly glyph: IconGlyph;\n readonly owner: string;\n /** Registered with `override`, over a table's glyph. */\n readonly overridden: boolean;\n}\n\n/** Thrown when a table claims a namespace another owner holds. */\nexport class IconNamespaceClaimedError extends Error {\n constructor(readonly namespace: string, readonly owner: string, readonly claimant: string) {\n super(`icon namespace \"${namespace}\" belongs to ${owner}; ${claimant} cannot register under it`);\n this.name = 'IconNamespaceClaimedError';\n }\n}\n\n/** Resolves icon refs to glyphs across registered tables and overrides, and reports who owns each namespace. */\nexport interface IconRegistry {\n get(ref: string): IconGlyph | undefined;\n add(tables: IconTable | readonly IconTable[]): () => void;\n override(ref: IconRef, glyph: IconGlyph, source?: string): () => void;\n owner(namespace: string): string | undefined;\n /** The same array until the registry next changes, so it is safe to read through `useSyncExternalStore`. */\n entries(): readonly IconEntry[];\n provideVariants(loaders: Readonly<Record<string, IconVariantLoader>>): void;\n loadVariant(name: string): Promise<void>;\n variantState(name: string): IconVariantState;\n subscribe(listener: () => void): () => void;\n getVersion(): number;\n}\n\nconst OVERRIDE = 'override';\n\ninterface Layer {\n readonly glyph: IconGlyph;\n readonly owner: string;\n}\n\ninterface Slot {\n /** One layer per live table, oldest first; the newest is what the table side shows. */\n readonly tables: Map<object, Layer>;\n /** Explicit overrides, oldest first; the newest covers every table layer. */\n readonly overrides: Layer[];\n}\n\nconst lastOf = <T>(it: Iterable<T>): T | undefined => {\n let last: T | undefined;\n for (const v of it) last = v;\n return last;\n};\n\n/** A registry, optionally seeded with tables; each `add` and `override` returns its own release function. */\nexport function createIconRegistry(initial?: IconTable | readonly IconTable[]): IconRegistry {\n const slots = new Map<string, Slot>();\n // How many live tables hold each namespace, and whose it is while any do.\n const claims = new Map<string, { owner: string; count: number }>();\n const notify = createEmitter();\n let version = 0;\n let snapshot: { version: number; entries: readonly IconEntry[] } | null = null;\n const changed = () => {\n version++;\n notify.emit();\n };\n\n const slotFor = (key: string): Slot => {\n let slot = slots.get(key);\n if (!slot) slots.set(key, (slot = { tables: new Map(), overrides: [] }));\n return slot;\n };\n const prune = (key: string) => {\n const slot = slots.get(key);\n if (slot && slot.tables.size === 0 && slot.overrides.length === 0) slots.delete(key);\n };\n const live = (slot: Slot | undefined): Layer | undefined =>\n slot && (slot.overrides.at(-1) ?? lastOf(slot.tables.values()));\n\n const unclaim = (namespace: string) => {\n const held = claims.get(namespace);\n if (!held) return;\n if (held.count <= 1) claims.delete(namespace);\n else claims.set(namespace, { ...held, count: held.count - 1 });\n };\n\n const add = (tables: IconTable | readonly IconTable[]): (() => void) => {\n const list = Array.isArray(tables) ? tables : [tables as IconTable];\n // Check every claim, those within the batch included, before writing any: a refused batch registers nothing.\n const pending = new Map<string, string>();\n for (const t of list) {\n const owner = claims.get(t.namespace)?.owner ?? pending.get(t.namespace);\n if (owner !== undefined && owner !== t.owner) throw new IconNamespaceClaimedError(t.namespace, owner, t.owner);\n pending.set(t.namespace, t.owner);\n }\n const releases = list.map((t) => {\n const held = claims.get(t.namespace);\n claims.set(t.namespace, { owner: t.owner, count: (held?.count ?? 0) + 1 });\n const token = {};\n const keys = Object.keys(t.icons).map((name) => `${t.namespace}:${name}`);\n for (const key of keys) {\n slotFor(key).tables.set(token, { glyph: t.icons[key.slice(t.namespace.length + 1)]!, owner: t.owner });\n }\n let released = false;\n return () => {\n if (released) return;\n released = true;\n unclaim(t.namespace);\n for (const key of keys) {\n slots.get(key)?.tables.delete(token);\n prune(key);\n }\n };\n });\n changed();\n return () => {\n releases.forEach((r) => r());\n changed();\n };\n };\n\n const variants = createVariants((tables) => void add(tables), changed);\n if (initial) add(initial);\n\n return {\n get: (ref) => live(slots.get(ref))?.glyph,\n add,\n override(ref, glyph, source = OVERRIDE) {\n const layer: Layer = { glyph, owner: source };\n slotFor(ref).overrides.push(layer);\n changed();\n return () => {\n const slot = slots.get(ref);\n const i = slot ? slot.overrides.indexOf(layer) : -1;\n if (i === -1) return;\n slot!.overrides.splice(i, 1);\n prune(ref);\n changed();\n };\n },\n owner: (namespace) => claims.get(namespace)?.owner,\n entries() {\n if (snapshot?.version === version) return snapshot.entries;\n const entries: IconEntry[] = [];\n for (const [key, slot] of slots) {\n const top = live(slot)!;\n entries.push({ ref: key as IconRef, glyph: top.glyph, owner: top.owner, overridden: slot.overrides.length > 0 });\n }\n snapshot = { version, entries: Object.freeze(entries) };\n return snapshot.entries;\n },\n provideVariants: variants.provide,\n loadVariant: variants.load,\n variantState: variants.state,\n subscribe: notify.subscribe,\n getVersion: () => version,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/names.ts","../src/variants.ts","../src/registry.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { QualifiedIconName } from './index.ts';\n\ndeclare const brand: unique symbol;\n\n/** A qualified icon name (`namespace:name`) that came from `icon()` or `toIconRef`. */\nexport type IconRef = string & { readonly [brand]: 'IconRef' };\n\nconst QUALIFIED = /^([^:\\s]+):([^:\\s]+)$/;\n\n/** `name` in `namespace`, unless it already names one. */\nexport function qualify(namespace: string, name: string): string {\n return name.includes(':') ? name : `${namespace}:${name}`;\n}\n\n/** The two halves of a qualified ref, or `undefined` for anything else. */\nexport function splitIconRef(ref: string): { namespace: string; name: string } | undefined {\n const m = QUALIFIED.exec(ref);\n return m ? { namespace: m[1]!, name: m[2]! } : undefined;\n}\n\n/** A string read at run time (a schema loaded as JSON) as a ref, when it is qualified. */\nexport function toIconRef(value: string | undefined): IconRef | undefined {\n return value !== undefined && QUALIFIED.test(value) ? (value as IconRef) : undefined;\n}\n\n/** A package's `icon()`: bare names resolve in `namespace` only. Generated into each package's `icons.gen.ts`. */\nexport function scopedIcon<Own extends string>(namespace: string) {\n return (name: Own | QualifiedIconName): IconRef => qualify(namespace, name) as IconRef;\n}\n","import { isDev } from '@weasel-js/registry';\nimport type { IconTable, IconVariantLoader } from './table';\n\n/** Where a named icon variant stands: no loader for it (`unknown`), a loader not yet run (`idle`), in flight, in, or failed. */\nexport type IconVariantState = 'unknown' | 'idle' | 'loading' | 'loaded' | 'failed';\n\n/** Loads each named variant at most once at a time; a failure leaves it retryable. */\nexport function createVariants(addTables: (tables: readonly IconTable[]) => void, changed: () => void) {\n const loaders = new Map<string, IconVariantLoader>();\n const states = new Map<string, IconVariantState>();\n const pending = new Map<string, Promise<void>>();\n\n const set = (name: string, state: IconVariantState) => {\n states.set(name, state);\n changed();\n };\n\n return {\n provide(next: Readonly<Record<string, IconVariantLoader>>): void {\n for (const [name, loader] of Object.entries(next)) {\n loaders.set(name, loader);\n if (!states.has(name)) states.set(name, 'idle');\n }\n changed();\n },\n state(name: string): IconVariantState {\n return states.get(name) ?? 'unknown';\n },\n load(name: string): Promise<void> {\n const loader = loaders.get(name);\n if (!loader || states.get(name) === 'loaded') return Promise.resolve();\n const inFlight = pending.get(name);\n if (inFlight) return inFlight;\n set(name, 'loading');\n const run = Promise.resolve()\n .then(loader)\n .then((mod) => {\n addTables(mod.default);\n set(name, 'loaded');\n })\n .catch((error: unknown) => {\n if (isDev()) console.error(`icon variant \"${name}\" failed to load`, error);\n set(name, 'failed');\n })\n .finally(() => pending.delete(name));\n pending.set(name, run);\n return run;\n },\n };\n}\n","import { createEmitter } from '@weasel-js/registry';\nimport type { IconRef } from './names';\nimport type { IconGlyph, IconTable, IconVariantLoader } from './table';\nimport { createVariants, type IconVariantState } from './variants';\n\nexport type { IconVariantState } from './variants';\n\n/** One icon as the registry reports it. */\nexport interface IconEntry {\n readonly ref: IconRef;\n readonly glyph: IconGlyph;\n readonly owner: string;\n /** Registered with `override`, over a table's glyph. */\n readonly overridden: boolean;\n}\n\n/** Thrown when a table claims a namespace another owner holds. */\nexport class IconNamespaceClaimedError extends Error {\n constructor(readonly namespace: string, readonly owner: string, readonly claimant: string) {\n super(`icon namespace \"${namespace}\" belongs to ${owner}; ${claimant} cannot register under it`);\n this.name = 'IconNamespaceClaimedError';\n }\n}\n\n/** Resolves icon refs to glyphs across registered tables and overrides, and reports who owns each namespace. */\nexport interface IconRegistry {\n get(ref: string): IconGlyph | undefined;\n add(tables: IconTable | readonly IconTable[]): () => void;\n override(ref: IconRef, glyph: IconGlyph, source?: string): () => void;\n owner(namespace: string): string | undefined;\n /** The same array until the registry next changes, so it is safe to read through `useSyncExternalStore`. */\n entries(): readonly IconEntry[];\n provideVariants(loaders: Readonly<Record<string, IconVariantLoader>>): void;\n loadVariant(name: string): Promise<void>;\n variantState(name: string): IconVariantState;\n subscribe(listener: () => void): () => void;\n getVersion(): number;\n}\n\nconst OVERRIDE = 'override';\n\ninterface Layer {\n readonly glyph: IconGlyph;\n readonly owner: string;\n}\n\ninterface Slot {\n /** One layer per live table, oldest first; the newest is what the table side shows. */\n readonly tables: Map<object, Layer>;\n /** Explicit overrides, oldest first; the newest covers every table layer. */\n readonly overrides: Layer[];\n}\n\nconst lastOf = <T>(it: Iterable<T>): T | undefined => {\n let last: T | undefined;\n for (const v of it) last = v;\n return last;\n};\n\n/** A registry, optionally seeded with tables; each `add` and `override` returns its own release function. */\nexport function createIconRegistry(initial?: IconTable | readonly IconTable[]): IconRegistry {\n const slots = new Map<string, Slot>();\n // How many live tables hold each namespace, and whose it is while any do.\n const claims = new Map<string, { owner: string; count: number }>();\n const notify = createEmitter();\n let version = 0;\n let snapshot: { version: number; entries: readonly IconEntry[] } | null = null;\n const changed = () => {\n version++;\n notify.emit();\n };\n\n const slotFor = (key: string): Slot => {\n let slot = slots.get(key);\n if (!slot) slots.set(key, (slot = { tables: new Map(), overrides: [] }));\n return slot;\n };\n const prune = (key: string) => {\n const slot = slots.get(key);\n if (slot && slot.tables.size === 0 && slot.overrides.length === 0) slots.delete(key);\n };\n const live = (slot: Slot | undefined): Layer | undefined =>\n slot && (slot.overrides.at(-1) ?? lastOf(slot.tables.values()));\n\n const unclaim = (namespace: string) => {\n const held = claims.get(namespace);\n if (!held) return;\n if (held.count <= 1) claims.delete(namespace);\n else claims.set(namespace, { ...held, count: held.count - 1 });\n };\n\n const add = (tables: IconTable | readonly IconTable[]): (() => void) => {\n const list = Array.isArray(tables) ? tables : [tables as IconTable];\n // Check every claim, those within the batch included, before writing any: a refused batch registers nothing.\n const pending = new Map<string, string>();\n for (const t of list) {\n const owner = claims.get(t.namespace)?.owner ?? pending.get(t.namespace);\n if (owner !== undefined && owner !== t.owner) throw new IconNamespaceClaimedError(t.namespace, owner, t.owner);\n pending.set(t.namespace, t.owner);\n }\n const releases = list.map((t) => {\n const held = claims.get(t.namespace);\n claims.set(t.namespace, { owner: t.owner, count: (held?.count ?? 0) + 1 });\n const token = {};\n const keys = Object.keys(t.icons).map((name) => `${t.namespace}:${name}`);\n for (const key of keys) {\n slotFor(key).tables.set(token, { glyph: t.icons[key.slice(t.namespace.length + 1)]!, owner: t.owner });\n }\n let released = false;\n return () => {\n if (released) return;\n released = true;\n unclaim(t.namespace);\n for (const key of keys) {\n slots.get(key)?.tables.delete(token);\n prune(key);\n }\n };\n });\n changed();\n return () => {\n releases.forEach((r) => r());\n changed();\n };\n };\n\n const variants = createVariants((tables) => void add(tables), changed);\n if (initial) add(initial);\n\n return {\n get: (ref) => live(slots.get(ref))?.glyph,\n add,\n override(ref, glyph, source = OVERRIDE) {\n const layer: Layer = { glyph, owner: source };\n slotFor(ref).overrides.push(layer);\n changed();\n return () => {\n const slot = slots.get(ref);\n const i = slot ? slot.overrides.indexOf(layer) : -1;\n if (i === -1) return;\n slot!.overrides.splice(i, 1);\n prune(ref);\n changed();\n };\n },\n owner: (namespace) => claims.get(namespace)?.owner,\n entries() {\n if (snapshot?.version === version) return snapshot.entries;\n const entries: IconEntry[] = [];\n for (const [key, slot] of slots) {\n const top = live(slot)!;\n entries.push({ ref: key as IconRef, glyph: top.glyph, owner: top.owner, overridden: slot.overrides.length > 0 });\n }\n snapshot = { version, entries: Object.freeze(entries) };\n return snapshot.entries;\n },\n provideVariants: variants.provide,\n loadVariant: variants.load,\n variantState: variants.state,\n subscribe: notify.subscribe,\n getVersion: () => version,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/icons",
3
- "version": "1.10.1",
3
+ "version": "1.11.0",
4
4
  "description": "Namespaced icon names and the icon registry. No React, no DOM, no glyphs of its own.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,6 +19,6 @@
19
19
  "engines": { "node": ">=22" },
20
20
  "files": ["dist", "README.md", "LICENSE"],
21
21
  "scripts": { "build": "tsup" },
22
- "dependencies": { "@weasel-js/registry": "1.10.1" },
22
+ "dependencies": { "@weasel-js/registry": "1.11.0" },
23
23
  "publishConfig": { "access": "public", "provenance": true }
24
24
  }