@hyperfixi/patterns-reference 2.9.1 → 2.9.3
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/data/engine-verification.json +4 -5
- package/dist/index.d.mts +73 -1
- package/dist/index.d.ts +73 -1
- package/dist/index.js +36 -0
- package/dist/index.mjs +36 -1
- package/package.json +5 -5
- package/src/html-snippets.ts +114 -0
- package/src/index.ts +8 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"bar": {
|
|
4
|
-
"lokascript": "compileSync(code).ok via @hyperfixi/core (same call as the browser _= path), with @hyperfixi/reactivity and @hyperfixi/realtime installed (both ship pre-installed in hyperfixi.js), plus a jsdom top-level install smoke (no error within 500ms settle window)",
|
|
4
|
+
"lokascript": "compileSync(code).ok with zero recovered errors via @hyperfixi/core (same call as the browser _= path), with @hyperfixi/reactivity and @hyperfixi/realtime installed (both ship pre-installed in hyperfixi.js), plus a jsdom top-level install smoke (no error within 500ms settle window)",
|
|
5
5
|
"hyperscript": "upstream _hyperscript parse with zero recovered errors (extensions loaded: socket, worker, eventsource); parse-level only",
|
|
6
6
|
"html": "HTML-markup patterns: each _= / script-tag snippet verified individually; hx-live/sse-*/ws-* attributes are hyperfixi-only and block the upstream claim"
|
|
7
7
|
},
|
|
8
|
-
"lokascriptVersion": "2.
|
|
8
|
+
"lokascriptVersion": "2.9.1",
|
|
9
9
|
"hyperscriptVersion": "0.9.93"
|
|
10
10
|
},
|
|
11
11
|
"engines": {
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"send-event-to-form": "both",
|
|
130
130
|
"send-with-detail": "both",
|
|
131
131
|
"set-attribute": "both",
|
|
132
|
-
"set-color-variable": "
|
|
132
|
+
"set-color-variable": "both",
|
|
133
133
|
"set-inner-html-possessive-dot": "both",
|
|
134
134
|
"set-opacity": "both",
|
|
135
135
|
"set-style": "both",
|
|
@@ -677,8 +677,7 @@
|
|
|
677
677
|
},
|
|
678
678
|
"set-color-variable": {
|
|
679
679
|
"lokascript": true,
|
|
680
|
-
"hyperscript":
|
|
681
|
-
"hyperscriptError": "Unexpected value: *"
|
|
680
|
+
"hyperscript": true
|
|
682
681
|
},
|
|
683
682
|
"set-inner-html-possessive-dot": {
|
|
684
683
|
"lokascript": true,
|
package/dist/index.d.mts
CHANGED
|
@@ -419,6 +419,77 @@ declare function queryPatternsForCommand(command: string, language?: string): Pr
|
|
|
419
419
|
*/
|
|
420
420
|
declare function getSupportedLanguages(): Promise<string[]>;
|
|
421
421
|
|
|
422
|
+
/**
|
|
423
|
+
* Extract hyperscript sources out of HTML markup, via the DOM.
|
|
424
|
+
*
|
|
425
|
+
* Shared by the two harnesses that need it: `scripts/verify-engines.ts` (which
|
|
426
|
+
* classifies each corpus pattern's `engine` column) and the testing-framework's
|
|
427
|
+
* shipped-sources validity gate.
|
|
428
|
+
*
|
|
429
|
+
* **Why the DOM and not a regex.** A raw-text regex over `.html` cannot tell a
|
|
430
|
+
* live attribute from a code sample: a `<pre>`/`<code>`/`.code` block showing
|
|
431
|
+
* escaped source (`<button _="…">`) matches just as well as the real
|
|
432
|
+
* thing. That is not hypothetical — it is how an earlier sweep "found" two
|
|
433
|
+
* malformed sources in `examples/events-and-dom/send-events.html` that were
|
|
434
|
+
* only ever display text. Parsing the markup makes the distinction structural:
|
|
435
|
+
* escaped text decodes into a text node, never into an attribute, so it cannot
|
|
436
|
+
* be reached by an attribute walk.
|
|
437
|
+
*
|
|
438
|
+
* Do not reuse `@hyperfixi/vite-plugin`'s scanner for this purpose — it is
|
|
439
|
+
* deliberately a regex (it scans partial source files that need not be
|
|
440
|
+
* well-formed HTML) and has exactly that blind spot.
|
|
441
|
+
*/
|
|
442
|
+
/**
|
|
443
|
+
* The DOM surface this module needs, declared structurally.
|
|
444
|
+
*
|
|
445
|
+
* This package compiles with `lib: ["ES2022"]` (it is Node-oriented — a SQLite
|
|
446
|
+
* pattern database), so the ambient `Document`/`Element` types are not in
|
|
447
|
+
* scope. Declaring the three members used here keeps the extractor usable from
|
|
448
|
+
* a jsdom window, a browser document, or a happy-dom one without dragging the
|
|
449
|
+
* whole DOM lib into the package's build.
|
|
450
|
+
*/
|
|
451
|
+
interface MinimalAttr {
|
|
452
|
+
name: string;
|
|
453
|
+
value: string;
|
|
454
|
+
}
|
|
455
|
+
interface MinimalElement {
|
|
456
|
+
tagName: string;
|
|
457
|
+
attributes: ArrayLike<MinimalAttr>;
|
|
458
|
+
textContent: string | null;
|
|
459
|
+
getAttribute(name: string): string | null;
|
|
460
|
+
}
|
|
461
|
+
interface MinimalContainer extends MinimalElement {
|
|
462
|
+
innerHTML: string;
|
|
463
|
+
querySelectorAll(selectors: string): ArrayLike<MinimalElement>;
|
|
464
|
+
}
|
|
465
|
+
interface MinimalDocument {
|
|
466
|
+
createElement(tagName: string): MinimalContainer;
|
|
467
|
+
}
|
|
468
|
+
interface MarkupSnippets {
|
|
469
|
+
/** Every hyperscript source found, in document order. */
|
|
470
|
+
snippets: string[];
|
|
471
|
+
/**
|
|
472
|
+
* The markup uses at least one attribute upstream `_hyperscript` has no
|
|
473
|
+
* concept of, so it cannot be claimed as upstream-compatible regardless of
|
|
474
|
+
* how its snippets parse.
|
|
475
|
+
*/
|
|
476
|
+
hyperfixiOnly: boolean;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Pull every hyperscript source out of `markup`.
|
|
480
|
+
*
|
|
481
|
+
* Collects `_="…"` attributes, `hx-live="…"` values (which ARE hyperscript —
|
|
482
|
+
* the htmx-compat layer compiles them), and `<script type="text/hyperscript">`
|
|
483
|
+
* bodies. The other hyperfixi-only attribute values (`sse-connect` URLs,
|
|
484
|
+
* `sse-swap` event names, `ws-connect` URLs) are not hyperscript and carry no
|
|
485
|
+
* snippet to verify, but they do set `hyperfixiOnly`.
|
|
486
|
+
*
|
|
487
|
+
* `doc` is any DOM `Document` — a jsdom window's, or the ambient one in a
|
|
488
|
+
* browser/jsdom test environment. Markup that fails to parse yields no
|
|
489
|
+
* snippets rather than throwing.
|
|
490
|
+
*/
|
|
491
|
+
declare function extractHyperscriptFromMarkup(doc: MinimalDocument, markup: string): MarkupSnippets;
|
|
492
|
+
|
|
422
493
|
/**
|
|
423
494
|
* @hyperfixi/patterns-reference
|
|
424
495
|
*
|
|
@@ -456,9 +527,10 @@ declare function getSupportedLanguages(): Promise<string[]>;
|
|
|
456
527
|
* @returns PatternsReference instance
|
|
457
528
|
*/
|
|
458
529
|
declare function createPatternsReference(options?: ConnectionOptions): PatternsReference;
|
|
530
|
+
|
|
459
531
|
/**
|
|
460
532
|
* Version of the package.
|
|
461
533
|
*/
|
|
462
534
|
declare const VERSION = "0.1.0";
|
|
463
535
|
|
|
464
|
-
export { type BehaviorRuntime, Command, ConnectionOptions, DatabasePatternsProvider, Expression, Feature, type IntegrationResult, Keyword, LLMExample, type LLMExampleRecord, LanguageDocsStats, LanguageElement, LanguageElementType, type LoadBehaviorsOptions, type LoadBehaviorsResult, type PatternEntry, PatternsReference, type PatternsSource, type SemanticIntegrationOptions, SpecialSymbol, VERSION, buildFewShotContextSync, closeDatabase, createLLMAdapter, createPatternsProvider, createPatternsReference, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllSpecialSymbols, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultDbPath, getDefaultProvider, getExpressionByName, getExpressionsByCategory, getFeatureByName, getKeywordByName, getLLMExampleStats, getLanguageDocsStats, getSpecialSymbolByName, getSupportedLanguages, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, loadBehaviors, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, trackExampleUsage, uninitializeSemanticIntegration };
|
|
536
|
+
export { type BehaviorRuntime, Command, ConnectionOptions, DatabasePatternsProvider, Expression, Feature, type IntegrationResult, Keyword, LLMExample, type LLMExampleRecord, LanguageDocsStats, LanguageElement, LanguageElementType, type LoadBehaviorsOptions, type LoadBehaviorsResult, type MarkupSnippets, type PatternEntry, PatternsReference, type PatternsSource, type SemanticIntegrationOptions, SpecialSymbol, VERSION, buildFewShotContextSync, closeDatabase, createLLMAdapter, createPatternsProvider, createPatternsReference, extractHyperscriptFromMarkup, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllSpecialSymbols, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultDbPath, getDefaultProvider, getExpressionByName, getExpressionsByCategory, getFeatureByName, getKeywordByName, getLLMExampleStats, getLanguageDocsStats, getSpecialSymbolByName, getSupportedLanguages, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, loadBehaviors, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, trackExampleUsage, uninitializeSemanticIntegration };
|
package/dist/index.d.ts
CHANGED
|
@@ -419,6 +419,77 @@ declare function queryPatternsForCommand(command: string, language?: string): Pr
|
|
|
419
419
|
*/
|
|
420
420
|
declare function getSupportedLanguages(): Promise<string[]>;
|
|
421
421
|
|
|
422
|
+
/**
|
|
423
|
+
* Extract hyperscript sources out of HTML markup, via the DOM.
|
|
424
|
+
*
|
|
425
|
+
* Shared by the two harnesses that need it: `scripts/verify-engines.ts` (which
|
|
426
|
+
* classifies each corpus pattern's `engine` column) and the testing-framework's
|
|
427
|
+
* shipped-sources validity gate.
|
|
428
|
+
*
|
|
429
|
+
* **Why the DOM and not a regex.** A raw-text regex over `.html` cannot tell a
|
|
430
|
+
* live attribute from a code sample: a `<pre>`/`<code>`/`.code` block showing
|
|
431
|
+
* escaped source (`<button _="…">`) matches just as well as the real
|
|
432
|
+
* thing. That is not hypothetical — it is how an earlier sweep "found" two
|
|
433
|
+
* malformed sources in `examples/events-and-dom/send-events.html` that were
|
|
434
|
+
* only ever display text. Parsing the markup makes the distinction structural:
|
|
435
|
+
* escaped text decodes into a text node, never into an attribute, so it cannot
|
|
436
|
+
* be reached by an attribute walk.
|
|
437
|
+
*
|
|
438
|
+
* Do not reuse `@hyperfixi/vite-plugin`'s scanner for this purpose — it is
|
|
439
|
+
* deliberately a regex (it scans partial source files that need not be
|
|
440
|
+
* well-formed HTML) and has exactly that blind spot.
|
|
441
|
+
*/
|
|
442
|
+
/**
|
|
443
|
+
* The DOM surface this module needs, declared structurally.
|
|
444
|
+
*
|
|
445
|
+
* This package compiles with `lib: ["ES2022"]` (it is Node-oriented — a SQLite
|
|
446
|
+
* pattern database), so the ambient `Document`/`Element` types are not in
|
|
447
|
+
* scope. Declaring the three members used here keeps the extractor usable from
|
|
448
|
+
* a jsdom window, a browser document, or a happy-dom one without dragging the
|
|
449
|
+
* whole DOM lib into the package's build.
|
|
450
|
+
*/
|
|
451
|
+
interface MinimalAttr {
|
|
452
|
+
name: string;
|
|
453
|
+
value: string;
|
|
454
|
+
}
|
|
455
|
+
interface MinimalElement {
|
|
456
|
+
tagName: string;
|
|
457
|
+
attributes: ArrayLike<MinimalAttr>;
|
|
458
|
+
textContent: string | null;
|
|
459
|
+
getAttribute(name: string): string | null;
|
|
460
|
+
}
|
|
461
|
+
interface MinimalContainer extends MinimalElement {
|
|
462
|
+
innerHTML: string;
|
|
463
|
+
querySelectorAll(selectors: string): ArrayLike<MinimalElement>;
|
|
464
|
+
}
|
|
465
|
+
interface MinimalDocument {
|
|
466
|
+
createElement(tagName: string): MinimalContainer;
|
|
467
|
+
}
|
|
468
|
+
interface MarkupSnippets {
|
|
469
|
+
/** Every hyperscript source found, in document order. */
|
|
470
|
+
snippets: string[];
|
|
471
|
+
/**
|
|
472
|
+
* The markup uses at least one attribute upstream `_hyperscript` has no
|
|
473
|
+
* concept of, so it cannot be claimed as upstream-compatible regardless of
|
|
474
|
+
* how its snippets parse.
|
|
475
|
+
*/
|
|
476
|
+
hyperfixiOnly: boolean;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Pull every hyperscript source out of `markup`.
|
|
480
|
+
*
|
|
481
|
+
* Collects `_="…"` attributes, `hx-live="…"` values (which ARE hyperscript —
|
|
482
|
+
* the htmx-compat layer compiles them), and `<script type="text/hyperscript">`
|
|
483
|
+
* bodies. The other hyperfixi-only attribute values (`sse-connect` URLs,
|
|
484
|
+
* `sse-swap` event names, `ws-connect` URLs) are not hyperscript and carry no
|
|
485
|
+
* snippet to verify, but they do set `hyperfixiOnly`.
|
|
486
|
+
*
|
|
487
|
+
* `doc` is any DOM `Document` — a jsdom window's, or the ambient one in a
|
|
488
|
+
* browser/jsdom test environment. Markup that fails to parse yields no
|
|
489
|
+
* snippets rather than throwing.
|
|
490
|
+
*/
|
|
491
|
+
declare function extractHyperscriptFromMarkup(doc: MinimalDocument, markup: string): MarkupSnippets;
|
|
492
|
+
|
|
422
493
|
/**
|
|
423
494
|
* @hyperfixi/patterns-reference
|
|
424
495
|
*
|
|
@@ -456,9 +527,10 @@ declare function getSupportedLanguages(): Promise<string[]>;
|
|
|
456
527
|
* @returns PatternsReference instance
|
|
457
528
|
*/
|
|
458
529
|
declare function createPatternsReference(options?: ConnectionOptions): PatternsReference;
|
|
530
|
+
|
|
459
531
|
/**
|
|
460
532
|
* Version of the package.
|
|
461
533
|
*/
|
|
462
534
|
declare const VERSION = "0.1.0";
|
|
463
535
|
|
|
464
|
-
export { type BehaviorRuntime, Command, ConnectionOptions, DatabasePatternsProvider, Expression, Feature, type IntegrationResult, Keyword, LLMExample, type LLMExampleRecord, LanguageDocsStats, LanguageElement, LanguageElementType, type LoadBehaviorsOptions, type LoadBehaviorsResult, type PatternEntry, PatternsReference, type PatternsSource, type SemanticIntegrationOptions, SpecialSymbol, VERSION, buildFewShotContextSync, closeDatabase, createLLMAdapter, createPatternsProvider, createPatternsReference, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllSpecialSymbols, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultDbPath, getDefaultProvider, getExpressionByName, getExpressionsByCategory, getFeatureByName, getKeywordByName, getLLMExampleStats, getLanguageDocsStats, getSpecialSymbolByName, getSupportedLanguages, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, loadBehaviors, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, trackExampleUsage, uninitializeSemanticIntegration };
|
|
536
|
+
export { type BehaviorRuntime, Command, ConnectionOptions, DatabasePatternsProvider, Expression, Feature, type IntegrationResult, Keyword, LLMExample, type LLMExampleRecord, LanguageDocsStats, LanguageElement, LanguageElementType, type LoadBehaviorsOptions, type LoadBehaviorsResult, type MarkupSnippets, type PatternEntry, PatternsReference, type PatternsSource, type SemanticIntegrationOptions, SpecialSymbol, VERSION, buildFewShotContextSync, closeDatabase, createLLMAdapter, createPatternsProvider, createPatternsReference, extractHyperscriptFromMarkup, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllSpecialSymbols, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultDbPath, getDefaultProvider, getExpressionByName, getExpressionsByCategory, getFeatureByName, getKeywordByName, getLLMExampleStats, getLanguageDocsStats, getSpecialSymbolByName, getSupportedLanguages, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, loadBehaviors, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, trackExampleUsage, uninitializeSemanticIntegration };
|
package/dist/index.js
CHANGED
|
@@ -1347,6 +1347,41 @@ async function getSupportedLanguages() {
|
|
|
1347
1347
|
return provider.getSupportedLanguages();
|
|
1348
1348
|
}
|
|
1349
1349
|
|
|
1350
|
+
// src/html-snippets.ts
|
|
1351
|
+
var HYPERFIXI_ONLY_ATTR_PREFIXES = ["hx-live", "sse-", "ws-"];
|
|
1352
|
+
function extractHyperscriptFromMarkup(doc, markup) {
|
|
1353
|
+
const container = doc.createElement("div");
|
|
1354
|
+
try {
|
|
1355
|
+
container.innerHTML = markup;
|
|
1356
|
+
} catch {
|
|
1357
|
+
return { snippets: [], hyperfixiOnly: false };
|
|
1358
|
+
}
|
|
1359
|
+
const snippets = [];
|
|
1360
|
+
let hyperfixiOnly = false;
|
|
1361
|
+
for (const el of Array.from(container.querySelectorAll("*"))) {
|
|
1362
|
+
for (const attr of Array.from(el.attributes)) {
|
|
1363
|
+
if (attr.name === "_" && attr.value.trim()) {
|
|
1364
|
+
snippets.push(attr.value);
|
|
1365
|
+
}
|
|
1366
|
+
if (attr.name === "hx-live" && attr.value.trim()) {
|
|
1367
|
+
snippets.push(attr.value);
|
|
1368
|
+
}
|
|
1369
|
+
if (HYPERFIXI_ONLY_ATTR_PREFIXES.some((p) => attr.name.startsWith(p))) {
|
|
1370
|
+
hyperfixiOnly = true;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
if (el.tagName === "SCRIPT") {
|
|
1374
|
+
const type = el.getAttribute("type");
|
|
1375
|
+
if (type === "text/hyperscript-template") {
|
|
1376
|
+
hyperfixiOnly = true;
|
|
1377
|
+
} else if (type === "text/hyperscript" && el.textContent?.trim()) {
|
|
1378
|
+
snippets.push(el.textContent);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
return { snippets, hyperfixiOnly };
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1350
1385
|
// src/index.ts
|
|
1351
1386
|
function createPatternsReference(options) {
|
|
1352
1387
|
getDatabase(options);
|
|
@@ -1383,6 +1418,7 @@ exports.createPatternsProvider = createPatternsProvider;
|
|
|
1383
1418
|
exports.createPatternsReference = createPatternsReference;
|
|
1384
1419
|
exports.dbStampPath = dbStampPath;
|
|
1385
1420
|
exports.discoverPatterns = discoverPatterns;
|
|
1421
|
+
exports.extractHyperscriptFromMarkup = extractHyperscriptFromMarkup;
|
|
1386
1422
|
exports.findExamplesByCommand = findExamplesByCommand;
|
|
1387
1423
|
exports.findRelevantExamples = findRelevantExamples;
|
|
1388
1424
|
exports.getAllCommands = getAllCommands;
|
package/dist/index.mjs
CHANGED
|
@@ -1339,6 +1339,41 @@ async function getSupportedLanguages() {
|
|
|
1339
1339
|
return provider.getSupportedLanguages();
|
|
1340
1340
|
}
|
|
1341
1341
|
|
|
1342
|
+
// src/html-snippets.ts
|
|
1343
|
+
var HYPERFIXI_ONLY_ATTR_PREFIXES = ["hx-live", "sse-", "ws-"];
|
|
1344
|
+
function extractHyperscriptFromMarkup(doc, markup) {
|
|
1345
|
+
const container = doc.createElement("div");
|
|
1346
|
+
try {
|
|
1347
|
+
container.innerHTML = markup;
|
|
1348
|
+
} catch {
|
|
1349
|
+
return { snippets: [], hyperfixiOnly: false };
|
|
1350
|
+
}
|
|
1351
|
+
const snippets = [];
|
|
1352
|
+
let hyperfixiOnly = false;
|
|
1353
|
+
for (const el of Array.from(container.querySelectorAll("*"))) {
|
|
1354
|
+
for (const attr of Array.from(el.attributes)) {
|
|
1355
|
+
if (attr.name === "_" && attr.value.trim()) {
|
|
1356
|
+
snippets.push(attr.value);
|
|
1357
|
+
}
|
|
1358
|
+
if (attr.name === "hx-live" && attr.value.trim()) {
|
|
1359
|
+
snippets.push(attr.value);
|
|
1360
|
+
}
|
|
1361
|
+
if (HYPERFIXI_ONLY_ATTR_PREFIXES.some((p) => attr.name.startsWith(p))) {
|
|
1362
|
+
hyperfixiOnly = true;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
if (el.tagName === "SCRIPT") {
|
|
1366
|
+
const type = el.getAttribute("type");
|
|
1367
|
+
if (type === "text/hyperscript-template") {
|
|
1368
|
+
hyperfixiOnly = true;
|
|
1369
|
+
} else if (type === "text/hyperscript" && el.textContent?.trim()) {
|
|
1370
|
+
snippets.push(el.textContent);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return { snippets, hyperfixiOnly };
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1342
1377
|
// src/index.ts
|
|
1343
1378
|
function createPatternsReference(options) {
|
|
1344
1379
|
getDatabase(options);
|
|
@@ -1362,4 +1397,4 @@ function createPatternsReference(options) {
|
|
|
1362
1397
|
}
|
|
1363
1398
|
var VERSION = "0.1.0";
|
|
1364
1399
|
|
|
1365
|
-
export { DatabasePatternsProvider, VERSION, addLLMExample, buildFewShotContext, buildFewShotContextSync, checkDbStamp, closeDatabase, computeDbInputHash, createLLMAdapter, createPatternsProvider, createPatternsReference, dbStampPath, discoverPatterns, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllPatterns, getAllSpecialSymbols, getAllTranslations, getBehaviorPatterns, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultDbPath, getDefaultProvider, getExamplesByCommand, getExpressionByName, getExpressionsByCategory, getFeatureByName, getHighConfidenceTranslations, getHighQualityExamples, getKeywordByName, getLLMExampleStats, getLLMExamples, getLLMStats, getLanguageDocsStats, getMostUsedExamples, getPatternById, getPatternStats, getPatternsByCategory, getPatternsByCommand, getSpecialSymbolByName, getSupportedLanguages, getTranslation, getTranslationStats, getTranslationsByLanguage, getVerifiedTranslations, getWordOrder, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, loadBehaviors, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, searchPatterns, seedLLMExamples, syncTranslations, trackExampleUsage, uninitializeSemanticIntegration, updateQualityScore, validateAllTranslations, verifyTranslation, writeDbStamp };
|
|
1400
|
+
export { DatabasePatternsProvider, VERSION, addLLMExample, buildFewShotContext, buildFewShotContextSync, checkDbStamp, closeDatabase, computeDbInputHash, createLLMAdapter, createPatternsProvider, createPatternsReference, dbStampPath, discoverPatterns, extractHyperscriptFromMarkup, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllPatterns, getAllSpecialSymbols, getAllTranslations, getBehaviorPatterns, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultDbPath, getDefaultProvider, getExamplesByCommand, getExpressionByName, getExpressionsByCategory, getFeatureByName, getHighConfidenceTranslations, getHighQualityExamples, getKeywordByName, getLLMExampleStats, getLLMExamples, getLLMStats, getLanguageDocsStats, getMostUsedExamples, getPatternById, getPatternStats, getPatternsByCategory, getPatternsByCommand, getSpecialSymbolByName, getSupportedLanguages, getTranslation, getTranslationStats, getTranslationsByLanguage, getVerifiedTranslations, getWordOrder, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, loadBehaviors, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, searchPatterns, seedLLMExamples, syncTranslations, trackExampleUsage, uninitializeSemanticIntegration, updateQualityScore, validateAllTranslations, verifyTranslation, writeDbStamp };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperfixi/patterns-reference",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "Queryable patterns database for hyperscript with multilingual translations and LLM support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -66,13 +66,13 @@
|
|
|
66
66
|
},
|
|
67
67
|
"homepage": "https://github.com/codetalcott/hyperfixi/tree/main/packages/patterns-reference#readme",
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@lokascript/semantic": "^2.9.
|
|
69
|
+
"@lokascript/semantic": "^2.9.3",
|
|
70
70
|
"better-sqlite3": "^12.11.1"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@hyperfixi/core": "^2.9.
|
|
74
|
-
"@hyperfixi/reactivity": "^2.9.
|
|
75
|
-
"@hyperfixi/realtime": "^2.9.
|
|
73
|
+
"@hyperfixi/core": "^2.9.3",
|
|
74
|
+
"@hyperfixi/reactivity": "^2.9.3",
|
|
75
|
+
"@hyperfixi/realtime": "^2.9.3",
|
|
76
76
|
"@types/better-sqlite3": "^7.6.0",
|
|
77
77
|
"@types/node": "^20.0.0",
|
|
78
78
|
"hyperscript.org": "0.9.93",
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract hyperscript sources out of HTML markup, via the DOM.
|
|
3
|
+
*
|
|
4
|
+
* Shared by the two harnesses that need it: `scripts/verify-engines.ts` (which
|
|
5
|
+
* classifies each corpus pattern's `engine` column) and the testing-framework's
|
|
6
|
+
* shipped-sources validity gate.
|
|
7
|
+
*
|
|
8
|
+
* **Why the DOM and not a regex.** A raw-text regex over `.html` cannot tell a
|
|
9
|
+
* live attribute from a code sample: a `<pre>`/`<code>`/`.code` block showing
|
|
10
|
+
* escaped source (`<button _="…">`) matches just as well as the real
|
|
11
|
+
* thing. That is not hypothetical — it is how an earlier sweep "found" two
|
|
12
|
+
* malformed sources in `examples/events-and-dom/send-events.html` that were
|
|
13
|
+
* only ever display text. Parsing the markup makes the distinction structural:
|
|
14
|
+
* escaped text decodes into a text node, never into an attribute, so it cannot
|
|
15
|
+
* be reached by an attribute walk.
|
|
16
|
+
*
|
|
17
|
+
* Do not reuse `@hyperfixi/vite-plugin`'s scanner for this purpose — it is
|
|
18
|
+
* deliberately a regex (it scans partial source files that need not be
|
|
19
|
+
* well-formed HTML) and has exactly that blind spot.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** Attribute prefixes that only the hyperfixi htmx-compat layer implements. */
|
|
23
|
+
const HYPERFIXI_ONLY_ATTR_PREFIXES = ['hx-live', 'sse-', 'ws-'];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The DOM surface this module needs, declared structurally.
|
|
27
|
+
*
|
|
28
|
+
* This package compiles with `lib: ["ES2022"]` (it is Node-oriented — a SQLite
|
|
29
|
+
* pattern database), so the ambient `Document`/`Element` types are not in
|
|
30
|
+
* scope. Declaring the three members used here keeps the extractor usable from
|
|
31
|
+
* a jsdom window, a browser document, or a happy-dom one without dragging the
|
|
32
|
+
* whole DOM lib into the package's build.
|
|
33
|
+
*/
|
|
34
|
+
export interface MinimalAttr {
|
|
35
|
+
name: string;
|
|
36
|
+
value: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface MinimalElement {
|
|
40
|
+
tagName: string;
|
|
41
|
+
attributes: ArrayLike<MinimalAttr>;
|
|
42
|
+
textContent: string | null;
|
|
43
|
+
getAttribute(name: string): string | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface MinimalContainer extends MinimalElement {
|
|
47
|
+
innerHTML: string;
|
|
48
|
+
querySelectorAll(selectors: string): ArrayLike<MinimalElement>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface MinimalDocument {
|
|
52
|
+
createElement(tagName: string): MinimalContainer;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface MarkupSnippets {
|
|
56
|
+
/** Every hyperscript source found, in document order. */
|
|
57
|
+
snippets: string[];
|
|
58
|
+
/**
|
|
59
|
+
* The markup uses at least one attribute upstream `_hyperscript` has no
|
|
60
|
+
* concept of, so it cannot be claimed as upstream-compatible regardless of
|
|
61
|
+
* how its snippets parse.
|
|
62
|
+
*/
|
|
63
|
+
hyperfixiOnly: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Pull every hyperscript source out of `markup`.
|
|
68
|
+
*
|
|
69
|
+
* Collects `_="…"` attributes, `hx-live="…"` values (which ARE hyperscript —
|
|
70
|
+
* the htmx-compat layer compiles them), and `<script type="text/hyperscript">`
|
|
71
|
+
* bodies. The other hyperfixi-only attribute values (`sse-connect` URLs,
|
|
72
|
+
* `sse-swap` event names, `ws-connect` URLs) are not hyperscript and carry no
|
|
73
|
+
* snippet to verify, but they do set `hyperfixiOnly`.
|
|
74
|
+
*
|
|
75
|
+
* `doc` is any DOM `Document` — a jsdom window's, or the ambient one in a
|
|
76
|
+
* browser/jsdom test environment. Markup that fails to parse yields no
|
|
77
|
+
* snippets rather than throwing.
|
|
78
|
+
*/
|
|
79
|
+
export function extractHyperscriptFromMarkup(doc: MinimalDocument, markup: string): MarkupSnippets {
|
|
80
|
+
const container = doc.createElement('div');
|
|
81
|
+
try {
|
|
82
|
+
container.innerHTML = markup;
|
|
83
|
+
} catch {
|
|
84
|
+
return { snippets: [], hyperfixiOnly: false };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const snippets: string[] = [];
|
|
88
|
+
let hyperfixiOnly = false;
|
|
89
|
+
|
|
90
|
+
for (const el of Array.from(container.querySelectorAll('*'))) {
|
|
91
|
+
for (const attr of Array.from(el.attributes)) {
|
|
92
|
+
if (attr.name === '_' && attr.value.trim()) {
|
|
93
|
+
snippets.push(attr.value);
|
|
94
|
+
}
|
|
95
|
+
if (attr.name === 'hx-live' && attr.value.trim()) {
|
|
96
|
+
snippets.push(attr.value);
|
|
97
|
+
}
|
|
98
|
+
if (HYPERFIXI_ONLY_ATTR_PREFIXES.some(p => attr.name.startsWith(p))) {
|
|
99
|
+
hyperfixiOnly = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (el.tagName === 'SCRIPT') {
|
|
104
|
+
const type = el.getAttribute('type');
|
|
105
|
+
if (type === 'text/hyperscript-template') {
|
|
106
|
+
hyperfixiOnly = true;
|
|
107
|
+
} else if (type === 'text/hyperscript' && el.textContent?.trim()) {
|
|
108
|
+
snippets.push(el.textContent);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return { snippets, hyperfixiOnly };
|
|
114
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -275,6 +275,14 @@ export function createPatternsReference(options?: ConnectionOptions): PatternsRe
|
|
|
275
275
|
};
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
/**
|
|
279
|
+
* DOM-based extraction of hyperscript out of HTML markup. Shared with the
|
|
280
|
+
* testing-framework's shipped-sources validity gate so both harnesses agree on
|
|
281
|
+
* what counts as a live source (and neither regresses to a regex).
|
|
282
|
+
*/
|
|
283
|
+
export { extractHyperscriptFromMarkup } from './html-snippets';
|
|
284
|
+
export type { MarkupSnippets } from './html-snippets';
|
|
285
|
+
|
|
278
286
|
/**
|
|
279
287
|
* Version of the package.
|
|
280
288
|
*/
|