@jackens/nnn 2026.9.9 → 2026.9.29

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.
Files changed (5) hide show
  1. package/README.md +1229 -0
  2. package/nnn.d.ts +180 -204
  3. package/nnn.js +84 -95
  4. package/package.json +3 -14
  5. package/readme.md +0 -1370
package/nnn.d.ts CHANGED
@@ -1,244 +1,220 @@
1
- /**
2
- * Represents a CSS rule node for the {@link c} helper. Keys
3
- * are CSS properties or nested selectors.
4
- */
1
+ /** Represents a CSS rule node for the {@link c} helper. Keys are CSS properties or nested selectors. */
5
2
  export type CNode = {
6
- [attributeOrSelector: string]: string | number | CNode | undefined;
7
- };
3
+ [attributeOrSelector: string]: string | number | CNode | undefined
4
+ }
8
5
  /**
9
- * A minimal CSS-in-JS helper that converts a JavaScript
10
- * object hierarchy into a CSS string.
11
- *
12
- * @param node An object describing CSS rules. Keys are
13
- * selectors or at-rules; values are either CSS property
14
- * values or nested rule objects. A selector key may
15
- * contain comma-separated alternatives (e.g. `'.b,.c'`);
16
- * when nested, each alternative is combined with each
17
- * parent alternative (cartesian product), producing a
18
- * comma-joined selector list (e.g. `'a.b,a.c'`).
19
- * @param splitter A delimiter used to create unique keys
20
- * (default: `'$$'`). The substring from `splitter` to the
21
- * end of a key is ignored (e.g., `src$$1` → `src`).
22
- *
23
- * @returns A CSS string representing the compiled rules.
6
+ * A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
7
+ *
8
+ * @param node
9
+ *
10
+ * An object describing CSS rules.
11
+ * Keys are selectors or at-rules; values are either CSS property values or nested rule objects.
12
+ * Nested selectors are appended to the parent selector as is (e.g. `'.c'` inside `a` → `a.c`), so a leading space is needed for a descendant combinator (e.g. `' .c'` → `a .c`).
13
+ * A selector key may contain comma-separated alternatives (e.g. `'.b,.c'`); when nested, each alternative is combined with each parent alternative (cartesian product), producing a comma-joined selector list (e.g. `'a.b,a.c'`).
14
+ * Top-level at-rules (e.g. `'@media …'`) wrap their nested rules; inside a top-level `:root` rule nested keys are concatenated into property names (e.g. `{ ':root': { '--': { bg: 'red' } } }` → `:root{--bg:red}`).
15
+ * `null`/`undefined` values are skipped.
16
+ *
17
+ * @param splitter
18
+ *
19
+ * A delimiter used to create unique keys (default: `'$$'`).
20
+ * The substring from `splitter` to the end of a key is ignored (e.g. `src$$1` → `src`).
21
+ *
22
+ * @returns
23
+ *
24
+ * A CSS string representing the compiled rules.
24
25
  */
25
- export declare const c: (node: CNode, splitter?: string) => string;
26
+ export declare const c: (node: CNode, splitter?: string) => string
26
27
  /**
27
- * Creates a tag function for escaping interpolated values
28
- * in template literals.
28
+ * Options of a {@link createLexer} spec controlling the lexer state stack.
29
+ *
30
+ * @property in
31
+ *
32
+ * State(s) in which the spec is active (default: `'root'`).
33
+ *
34
+ * @property pop
29
35
  *
30
- * @param escapeFn A function that takes a value and returns
31
- * its escaped string representation.
36
+ * Whether to pop the current state off the stack after a match (the `'root'` state at the bottom is never popped).
32
37
  *
33
- * @returns A tag function that escapes interpolated values
34
- * using the provided escape function.
38
+ * @property push
39
+ *
40
+ * State to push onto the stack after a match (applied after `pop`).
35
41
  */
36
- export declare const createEscape: (escapeFn: (value: any) => string) => (template: TemplateStringsArray, ...values: unknown[]) => string;
42
+ export type LexerSpecOptions = {
43
+ in?: string | string[]
44
+ pop?: boolean
45
+ push?: string
46
+ }
47
+ /** A {@link createLexer} spec: a `[metadata, pattern, options?]` tuple. */
48
+ export type LexerSpec<M> = [metadata: M, pattern: string | RegExp, options?: LexerSpecOptions]
37
49
  /**
38
- * A helper for building simple tokenizers (see also
39
- * {@link nanolightTs}).
50
+ * A helper for building simple stateful lexers (see also {@link nanolightTs}).
40
51
  *
41
52
  * @remarks
42
53
  *
43
- * 1. Matches starting at an earlier position take
44
- * precedence.
45
- * 2. Among matches at the same position, the longer one
46
- * wins.
47
- * 3. Among matches of the same position and length, the one
48
- * defined earlier wins.
49
- *
50
- * @param decorator A function that wraps each matched
51
- * chunk. It receives the matched text (`chunk`) and
52
- * optionally the `metadata` associated with the pattern
53
- * that produced the match. For unmatched text between
54
- * patterns, `metadata` is `undefined`.
55
- * @param specs An array of tuples `[metadata, pattern]`
56
- * where:
57
- *
58
- * - `metadata`: arbitrary data (e.g., a CSS class name)
59
- * passed to `decorator` when the pattern matches.
60
- * - `pattern`: a `string` or `RegExp` to match against the
61
- * input.
62
- *
63
- * @returns A tokenizer function that accepts a code string
64
- * and returns an array of decorated tokens.
65
- */
66
- export declare const createTokenizer: <M, T>(decorator: (chunk: string, metadata?: M) => T, ...specs: [M, string | RegExp][]) => (code: string) => T[];
67
- /**
68
- * Parses a CSV string into a two-dimensional array of
69
- * strings.
54
+ * 1. Matches starting at an earlier position take precedence.
55
+ * 2. Among matches at the same position, the longer one wins.
56
+ * 3. Among matches of the same position and length, the one defined earlier wins.
57
+ * 4. Only specs active in the current state (the top of the state stack, initially `'root'`) are considered.
58
+ * 5. Patterns are matched against the whole input, so `^`, `$`, `\b` and lookbehinds see the text around the current position; a sticky (`y`) `RegExp` matches only at the current position.
59
+ * 6. Empty matches are ignored.
70
60
  *
71
- * Supports quoted fields with escaped double quotes (`""`).
72
- * Carriage returns are normalized.
61
+ * @param decorator
73
62
  *
74
- * @param csv The CSV string to parse.
75
- * @param separator The field delimiter (default: `','`).
63
+ * A function that wraps each chunk of the input.
64
+ * It receives the matched text (`chunk`) and the `metadata` of the spec whose pattern produced the match.
65
+ * For unmatched text between matches, `metadata` is `undefined`.
76
66
  *
77
- * @returns A 2D array where each inner array represents a
78
- * row of fields.
79
- */
80
- export declare const csvParse: (csv: string, separator?: string) => string[][];
81
- /**
82
- * Applies Polish-specific typographic corrections to a DOM
83
- * subtree.
84
- *
85
- * This function prevents orphaned conjunctions
86
- * (single-letter words like “a”, “i”, “o”, “u”, “w”, “z”)
87
- * and the em dash (“—”) from appearing at the end of a
88
- * line. It wraps each such character together with the
89
- * whitespace that follows it in a `white-space:nowrap`
90
- * span, removing the only line-break opportunity between it
91
- * and the next word so the two stay glued together. It also
92
- * inserts zero-width spaces after slashes and dots to allow
93
- * line breaks.
94
- *
95
- * @param node The root DOM node to process. All descendant
96
- * text nodes are corrected recursively, except those
97
- * inside `IFRAME`, `NOSCRIPT`, `PRE`, `SCRIPT`, `STYLE`,
98
- * or `TEXTAREA` elements.
99
- */
100
- export declare const fixPlTypography: (node: Node) => void;
101
- /**
102
- * Single argument type for the {@link h} and {@link s}
103
- * helpers.
104
- */
105
- export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs;
106
- /**
107
- * Tuple argument type for the {@link h} and {@link s}
108
- * helpers.
67
+ * @param specs
68
+ *
69
+ * An array of tuples `[metadata, pattern, options?]` where:
70
+ *
71
+ * - `metadata`: arbitrary data (e.g., a CSS class name) passed to `decorator` when the pattern matches.
72
+ * - `pattern`: a `string` (matched literally) or `RegExp` to match against the input.
73
+ * - `options`: optional {@link LexerSpecOptions} (states in which the spec is active and state transitions).
74
+ *
75
+ * @returns
76
+ *
77
+ * A lexer function that accepts an input string and returns an array of decorated chunks covering the whole input (in order).
109
78
  */
110
- export type HArgs = [string | Node, ...HArgs1[]];
79
+ export declare const createLexer: <M, T>(
80
+ decorator: (chunk: string, metadata?: M) => T,
81
+ ...specs: LexerSpec<M>[]
82
+ ) => (code: string) => T[]
83
+ /** Single argument type for the {@link h} and {@link s} helpers. */
84
+ export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs
85
+ /** Tuple argument type for the {@link h} and {@link s} helpers. */
86
+ export type HArgs = [string | Node, ...HArgs1[]]
111
87
  /**
112
- * A lightweight _HyperScript_-style helper for creating and
113
- * modifying `HTMLElement`s (see also {@link s}).
114
- *
115
- * @param tagOrNode If a `string`, it is treated as the tag
116
- * name for a new element. If a `Node`, that node is
117
- * modified in place.
118
- * @param args Additional arguments processed as follows:
119
- *
120
- * - `Object`: maps attributes/properties. Keys starting
121
- * with `$` set element properties (without the `$`
122
- * prefix); if the value is a plain object, it is
123
- * shallow-merged into the existing property instead of
124
- * replacing it (useful e.g. for `$style`). Other keys
125
- * set attributes: a key prefixed with `xlink:` sets the
126
- * attribute via `setAttributeNS` in the XLink
127
- * namespace; any other key (without a colon) sets it
128
- * via `setAttribute`. A value of `false` removes the
129
- * attribute.
130
- * - `null`/`undefined`: ignored.
131
- * - `Node`: appended as a child.
132
- * - `string`/`number`: converted to a `Text` node and
133
- * appended.
134
- * - {@link HArgs} array: processed recursively.
135
- *
136
- * @returns The created or modified `HTMLElement`.
88
+ * A lightweight _HyperScript_-style helper for creating and modifying `HTMLElement`s (see also {@link s}).
89
+ *
90
+ * @param tagOrNode
91
+ *
92
+ * If a `string`, it is treated as the tag name for a new element.
93
+ * If a `Node`, that node is modified in place.
94
+ *
95
+ * @param args
96
+ *
97
+ * Additional arguments processed as follows:
98
+ *
99
+ * - `Object`: maps attributes/properties.
100
+ * - Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object, it is shallow-merged into the existing property instead of replacing it (useful e.g. for `$style`).
101
+ * - Other keys set attributes: a key prefixed with `xlink:` sets the attribute via `setAttributeNS` in the XLink namespace; any other key (without a colon) sets it via `setAttribute`.
102
+ * A value of `true` sets an empty attribute (e.g. `checked=""`), a value of `false` removes the attribute.
103
+ * - `null`/`undefined`: ignored.
104
+ * - `Node`: appended as a child.
105
+ * - `string`/`number`: converted to a `Text` node and appended.
106
+ * - {@link HArgs} array: processed recursively (creates or modifies a child node and appends it).
107
+ *
108
+ * @returns
109
+ *
110
+ * The created `HTMLElement` or the modified node.
137
111
  */
138
112
  export declare const h: {
139
- <T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1[]): HTMLElementTagNameMap[T];
140
- <N extends Node>(node: N, ...args1: HArgs1[]): N;
141
- (tagOrNode: string | Node, ...args1: HArgs1[]): Node;
142
- };
113
+ <T extends keyof HTMLElementTagNameMap>(tag: T, ...args: HArgs1[]): HTMLElementTagNameMap[T]
114
+ <N extends Node>(node: N, ...args: HArgs1[]): N
115
+ (tagOrNode: string | Node, ...args: HArgs1[]): Node
116
+ }
143
117
  /**
144
- * A lightweight _HyperScript_-style helper for creating and
145
- * modifying `SVGElement`s (see also {@link h}).
146
- *
147
- * @param tagOrNode If a `string`, it is treated as the tag
148
- * name for a new element. If a `Node`, that node is
149
- * modified in place.
150
- * @param args Additional arguments processed as follows:
151
- *
152
- * - `Object`: maps attributes/properties. Keys starting
153
- * with `$` set element properties (without the `$`
154
- * prefix); if the value is a plain object, it is
155
- * shallow-merged into the existing property instead of
156
- * replacing it. Other keys set attributes: a key
157
- * prefixed with `xlink:` sets the attribute via
158
- * `setAttributeNS` in the XLink namespace; any other
159
- * key (without a colon) sets it via `setAttribute`. A
160
- * value of `false` removes the attribute.
161
- * - `null`/`undefined`: ignored.
162
- * - `Node`: appended as a child.
163
- * - `string`/`number`: converted to a `Text` node and
164
- * appended.
165
- * - {@link HArgs} array: processed recursively.
166
- *
167
- * @returns The created or modified `SVGElement`.
118
+ * A lightweight _HyperScript_-style helper for creating and modifying `SVGElement`s (see also {@link h}).
119
+ *
120
+ * @param tagOrNode
121
+ *
122
+ * If a `string`, it is treated as the tag name for a new element.
123
+ * If a `Node`, that node is modified in place.
124
+ *
125
+ * @param args
126
+ *
127
+ * Additional arguments processed as follows:
128
+ *
129
+ * - `Object`: maps attributes/properties.
130
+ * - Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object, it is shallow-merged into the existing property instead of replacing it.
131
+ * - Other keys set attributes: a key prefixed with `xlink:` sets the attribute via `setAttributeNS` in the XLink namespace; any other key (without a colon) sets it via `setAttribute`.
132
+ * A value of `true` sets an empty attribute (e.g. `checked=""`), a value of `false` removes the attribute.
133
+ * - `null`/`undefined`: ignored.
134
+ * - `Node`: appended as a child.
135
+ * - `string`/`number`: converted to a `Text` node and appended.
136
+ * - {@link HArgs} array: processed recursively (creates or modifies a child node and appends it).
137
+ *
138
+ * @returns
139
+ *
140
+ * The created `SVGElement` or the modified node.
168
141
  */
169
142
  export declare const s: {
170
- <T extends keyof SVGElementTagNameMap>(tag: T, ...args1: HArgs1[]): SVGElementTagNameMap[T];
171
- <N extends Node>(node: N, ...args1: HArgs1[]): N;
172
- (tagOrNode: string | Node, ...args1: HArgs1[]): Node;
173
- };
143
+ <T extends keyof SVGElementTagNameMap>(tag: T, ...args: HArgs1[]): SVGElementTagNameMap[T]
144
+ <N extends Node>(node: N, ...args: HArgs1[]): N
145
+ (tagOrNode: string | Node, ...args: HArgs1[]): Node
146
+ }
174
147
  /**
175
- * Shorthand for creating an SVG element with a `<use>`
176
- * child referencing an icon by ID.
148
+ * Shorthand for creating an `<svg>` element with a `<use>` child referencing a symbol (e.g. an icon) by ID.
177
149
  *
178
150
  * Equivalent to:
179
151
  *
180
152
  * ```ts
181
- * s(
182
- * 'svg',
183
- * ['use', { 'xlink:href': '#' + id }],
184
- * ...args
185
- * )
153
+ * s('svg', ['use', { 'xlink:href': '#' + id }], ...args)
186
154
  * ```
187
155
  *
188
- * @param id The ID of the symbol to reference (without the
189
- * `#` prefix).
190
- * @param args Additional arguments passed to the outer
191
- * `<svg>` element.
156
+ * @param id
157
+ *
158
+ * The ID of the symbol to reference (without the `#` prefix).
159
+ *
160
+ * @param args
161
+ *
162
+ * Additional arguments passed to the outer `<svg>` element.
163
+ *
164
+ * @returns
192
165
  *
193
- * @returns An `SVGSVGElement` containing a `<use>` element.
166
+ * An `SVGSVGElement` containing a `<use>` element.
194
167
  */
195
- export declare const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement;
168
+ export declare const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement
196
169
  /**
197
- * A Monokai-inspired color scheme for use with the {@link c}
198
- * helper and {@link nanolightTs} tokenizer.
170
+ * A Monokai-inspired color scheme for use with the {@link c} helper and {@link nanolightTs} lexer.
171
+ * It styles `pre` and `code>span` elements with the class names produced by {@link nanolightTs} (with light, dark and print variants).
199
172
  */
200
- export declare const monokai: CNode;
173
+ export declare const monokai: CNode
201
174
  /**
202
- * A TypeScript/JavaScript syntax highlighting tokenizer
203
- * built using {@link createTokenizer}.
175
+ * A TypeScript/JavaScript syntax highlighting lexer built using {@link createLexer}.
204
176
  *
205
- * @param code The source code string to tokenize.
177
+ * @param code
206
178
  *
207
- * @returns An array of {@link HArgs1} elements suitable for
208
- * rendering with {@link h}.
209
- */
210
- export declare const nanolightTs: (code: string) => HArgs1[];
211
- /**
212
- * A responsive web design helper that generates CSS rules
213
- * for a grid-like layout.
214
- *
215
- * @param root The CSS root object to populate (see
216
- * {@link c}).
217
- * @param selector The CSS selector for the grid item.
218
- * @param cellWidthPx The base cell width in pixels.
219
- * @param cellHeightPx The base cell height in pixels.
220
- * @param specs An array of breakpoint specifications, each
221
- * a tuple of:
222
- *
223
- * - `maxWidth`: maximum number of cells per row (defines
224
- * the viewport breakpoint).
225
- * - `width` (optional, default `1`): number of horizontal
226
- * cells the element spans.
227
- * - `height` (optional, default `1`): number of vertical
228
- * cells the element spans.
179
+ * The source code string to tokenize.
180
+ *
181
+ * @returns
182
+ *
183
+ * An array of {@link HArgs1} elements suitable for rendering with {@link h}: plain `string`s for unrecognized text (e.g. whitespace) and `['span', { class }, chunk]` tuples for recognized tokens (class names are styled by {@link monokai}).
229
184
  */
230
- export declare const rwd: (root: CNode, selector: string, cellWidthPx: number, cellHeightPx: number, ...specs: [number, number?, number?][]) => void;
185
+ export declare const nanolightTs: (code: string) => HArgs1[]
231
186
  /**
232
- * Generates a UUID v1 (time-based) identifier.
187
+ * A responsive web design helper that generates CSS rules for a grid-like layout of floating elements.
188
+ * It modifies `root` in place: it sets base styles for `selector` and adds a `@media(min-width:…px)` rule for each breakpoint.
189
+ *
190
+ * @param root
191
+ *
192
+ * The CSS root object to populate (see {@link c}).
193
+ *
194
+ * @param selector
195
+ *
196
+ * The CSS selector for the grid item.
197
+ *
198
+ * @param cellWidthPx
199
+ *
200
+ * The base cell width in pixels.
201
+ *
202
+ * @param cellHeightPx
203
+ *
204
+ * The base cell height in pixels.
205
+ *
206
+ * @param specs
233
207
  *
234
- * @param date The date to use for the timestamp portion
235
- * (default: current date/time).
236
- * @param node A hexadecimal `string` for the node portion
237
- * (default: random). Must match `/^[0-9a-f]*$/`; it is
238
- * trimmed to the last 12 characters and left-padded with
239
- * zeros if shorter.
208
+ * An array of breakpoint specifications, each a tuple of:
240
209
  *
241
- * @returns A UUID v1 `string` in the standard format
242
- * `xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx`.
210
+ * - `maxWidth`: number of cells per row; the breakpoint is `min-width: cellWidthPx * maxWidth` (`1` modifies the base rule).
211
+ * - `width` (optional, default `1`): number of horizontal cells the element spans.
212
+ * - `height` (optional, default `1`): number of vertical cells the element spans.
243
213
  */
244
- export declare const uuidV1: (date?: Date, node?: string) => string;
214
+ export declare const rwd: (
215
+ root: CNode,
216
+ selector: string,
217
+ cellWidthPx: number,
218
+ cellHeightPx: number,
219
+ ...specs: [number, number?, number?][]
220
+ ) => void