@nitpicker/core 0.25.0 → 0.25.1
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/README.md +34 -34
- package/lib/to-u32-ids.js +0 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @nitpicker/core
|
|
2
2
|
|
|
3
|
-
Nitpicker の計算コアを Rust(Node-API、[napi-rs](https://napi.rs/))で実装したネイティブアドオンです。重い計算をここに集め、[@nitpicker/archive](../archive/README.md)
|
|
3
|
+
Nitpicker の計算コアを Rust(Node-API、[napi-rs](https://napi.rs/))で実装したネイティブアドオンです。重い計算をここに集め、[@nitpicker/archive](../archive/README.md)などの TypeScript パッケージから呼び出します。現在は、ページ本文の内容ハッシュ(`page_meta.body_hash`)、HTML の構造シグナルによる技術検出、URL の自然順の順位付け、alias の判定、リンクの連結成分、テンプレート分類(ページのシグナルと HTML から、ページごとのテンプレートキーとクラスタごとの reason まで)、保存済み HTML スナップショットに対する CSS セレクタの照合(`query match-selector`)と文字列・正規表現の検索(`query search-html`)を提供しています。
|
|
4
4
|
|
|
5
5
|
## 対応プラットフォーム
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ Nitpicker の計算コアを Rust(Node-API、[napi-rs](https://napi.rs/))で
|
|
|
11
11
|
| macOS(Apple silicon) | [@nitpicker/core-darwin-arm64](../core-darwin-arm64/README.md) |
|
|
12
12
|
| Linux x64・glibc 2.28 以上(WSL2 可) | [@nitpicker/core-linux-x64-gnu](../core-linux-x64-gnu/README.md) |
|
|
13
13
|
|
|
14
|
-
glibc 2.28 は Node.js 24 自体の Linux バイナリと同じ下限です。上記以外(Intel Mac、linux-arm64、musl、Windows
|
|
14
|
+
glibc 2.28 は Node.js 24 自体の Linux バイナリと同じ下限です。上記以外(Intel Mac、linux-arm64、musl、Windows ネイティブ)では、読み込んだ時点で対応表を含むエラーを出して終了します。プラットフォーム別パッケージは`optionalDependencies`で入るため、`--omit=optional`/`--no-optional`を付けてインストールすると読み込めません。
|
|
15
15
|
|
|
16
16
|
## 使い方
|
|
17
17
|
|
|
@@ -25,7 +25,7 @@ const b = computeBodyHash(Buffer.from('<body><a href="/p/z9y8x7w6">x</a></body>'
|
|
|
25
25
|
a.equals(b); // true — 動的 ID はマスクしてからハッシュする
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
フロントエンドフレームワークの構造シグナル(Next.js
|
|
28
|
+
フロントエンドフレームワークの構造シグナル(Next.js の`__NEXT_DATA__`、Vue の`data-v-*`など)は、`matchStructuralTechnologySignals`がページの HTML を 1 回走査して検出します。JS リソースの先頭にあるライセンスコメントは`matchJsLicenseCommentSignal`で照合します。フィンガープリントの一覧は`crates/nitpicker_tech_detect`が正です。
|
|
29
29
|
|
|
30
30
|
```ts
|
|
31
31
|
import { matchStructuralTechnologySignals } from '@nitpicker/core/match-structural-technology-signals';
|
|
@@ -34,7 +34,7 @@ matchStructuralTechnologySignals(Buffer.from('<div data-v-1a2b3c4d></div>'));
|
|
|
34
34
|
// [{ technology: 'Vue', signalType: 'scoped-attr', evidence: ' data-v-1a2b3c4d', weight: 40, category: 'JavaScript frameworks' }]
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
URL の自然順(`page2
|
|
37
|
+
URL の自然順(`page2`が`page10`の前、大文字小文字・パーセントエンコードで順序が割れない、ホストが先でパスが後)は、`computeUrlSortRanks`が全件まとめて順位にします。URL は 1 回だけパースし、結果は入力順に依存しない全順序です(同じ URL は入力順)。順序の定義は`crates/nitpicker_url_key`の doc が正です。
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
40
|
import { computeUrlSortRanks } from '@nitpicker/core/compute-url-sort-ranks';
|
|
@@ -46,7 +46,7 @@ computeUrlSortRanks([
|
|
|
46
46
|
]); // Uint32Array [2, 1, 0]
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
同じページが別の URL で現れている組(`content_items.alias_of_id`)の判定には、URL からスキーム・ホストの大文字小文字・`/index.{ext}
|
|
49
|
+
同じページが別の URL で現れている組(`content_items.alias_of_id`)の判定には、URL からスキーム・ホストの大文字小文字・`/index.{ext}`をたたんだ Tier A キーと、さらに末尾スラッシュを落とした Tier B キーを使います。`computeAliasKeys`が 1 回のパースで両方を返し、`groupAliasCandidates`がキー・タイトル・本文ハッシュで連結成分にまとめて代表を選びます(グループ内を指す canonical が最多 → 最短 URL → UTF-16 の昇順)。
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
import { computeAliasKeys } from '@nitpicker/core/compute-alias-keys';
|
|
@@ -55,7 +55,7 @@ computeAliasKeys('http://Example.com/about/index.html');
|
|
|
55
55
|
// { tierA: 'example.com/about/', tierB: 'example.com/about' }
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
リンクでつながったページの連結成分は、`createIsolatedClusterRun
|
|
58
|
+
リンクでつながったページの連結成分は、`createIsolatedClusterRun`で求めます。辺は SQLite から読んだ分ずつ`unionEdges`に渡して捨てるので、メモリはページ数に比例し、辺の数には比例しません。リダイレクト先・alias の先に解決してから結び、終わりのない連鎖(ループ、ループに合流する尾)の辺は捨てます。成分の番号は候補の並び順で振られ、辺の順序や分け方に依存しません。
|
|
59
59
|
|
|
60
60
|
```ts
|
|
61
61
|
import { createIsolatedClusterRun } from '@nitpicker/core/create-isolated-cluster-run';
|
|
@@ -66,7 +66,7 @@ run.unionEdges([10, 20, 20, 40]);
|
|
|
66
66
|
run.labels(); // Uint32Array [0, 0, 0]
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
保存済み HTML スナップショットのセレクタ照合は、`matchSelectorSnapshots
|
|
69
|
+
保存済み HTML スナップショットのセレクタ照合は、`matchSelectorSnapshots`がバッチ(`page_html_blobs`の行)を受け取り、zstd の展開から判定までをスレッドプールで並列に行って、スナップショットごとの判定を返します。同時に展開済みの文書を持つのは、スレッド数ぶんだけです。zstd のスナップショット 1 件の展開後は`MAX_DECODED_SNAPSHOT_BYTES`(`@nitpicker/core/max-decoded-snapshot-bytes`、約 1.5 GiB)までで、超えると「不一致」にせず、`snapshot <n> could not be decoded`で呼び出し全体を reject します。zstd のフレームヘッダが述べる展開後サイズは省略も偽りもできるので、展開しながら出てきたバイト数を数えて止めます。上限はクローラーが保存できる最大(V8 の文字列の最大長 2^29 − 24 code unit × UTF-8 の最大 3 バイト)なので、クローラーが保存したスナップショットが上限で弾かれることはありません。圧縮せずに保存されたスナップショットには掛けません(`searchHtmlSnapshots`も同じ)。1 文書だけを同期で判定する`matchSelectorHtml`は、テストとベンチの段階比較のために出しています。判定は、必要なリテラルが順に現れるかの事前判定、開始タグだけで決まるセレクタの開始タグ走査、結合子と`:nth-*`のための開タグスタックの順で、最も安い厳密な手段を使います。タグ名と属性名は ASCII の大文字小文字だけを無視します。計画(`SelectorPlan`)の作り方と解釈規則は`@nitpicker/cli`の`docs/query.md`が正です。
|
|
70
70
|
|
|
71
71
|
```ts
|
|
72
72
|
import { matchSelectorSnapshots } from '@nitpicker/core/match-selector-snapshots';
|
|
@@ -78,7 +78,7 @@ const verdicts = await matchSelectorSnapshots({
|
|
|
78
78
|
verdicts[0]; // { matched: true, prefiltered: false, tokenized: false }
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
保存済み HTML スナップショットの文字列・正規表現検索は、`searchHtmlSnapshots
|
|
81
|
+
保存済み HTML スナップショットの文字列・正規表現検索は、`searchHtmlSnapshots`がバッチを受け取り、展開から照合までを同じようにスレッドプールで並列に行って、スナップショットごとの`matchCount`(0 なら不一致)とスニペットを返します。パターンはスナップショットごとではなく 1 回だけコンパイルし、アドオンは直前にコンパイルしたパターンを保持して次のバッチでも使い回します(保持は 1 件だけなので、別のパターンの検索が並行すると入れ替わり、そのぶん再コンパイルします)。1 文書だけを同期で検索する`searchHtmlDocument`はテスト用、アーカイブを開く前にパターンを検証する`validateSearchPattern`は空文字列に一致するかを返し、構文エラーは`InvalidArg`で投げます。パターンは Rust の`regex` crate の構文(後方参照・先読み・後読みなし。照合時間は文書長に比例)で、マッチの単位は Unicode スカラー値、`\d` `\w` `\s` `\b`は Unicode の定義、`.`は`\r`と`\n`に一致せず、`m`の`^` `$`は CRLF を 1 つの行末として扱います。スニペットは、文書全体の空白を畳んでから窓を切ります。バッチの`bodies`は JS のバッファをコピーせず読むので、呼び出し側は promise が決着するまで書き換えないでください。永続化される値ではないので`(?-u)`は使わず、契約は`@nitpicker/cli`の`docs/query.md`(パターンの契約)が正です。
|
|
82
82
|
|
|
83
83
|
```ts
|
|
84
84
|
import { searchHtmlSnapshots } from '@nitpicker/core/search-html-snapshots';
|
|
@@ -97,7 +97,7 @@ const outcomes = await searchHtmlSnapshots({
|
|
|
97
97
|
outcomes[0]; // { matchCount: 2, snippet: '…fonts.example.org…' }
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
テンプレート分類は、呼び出し側(`@nitpicker/archive
|
|
100
|
+
テンプレート分類は、呼び出し側(`@nitpicker/archive`の`resolvePageClusterKeys`)がコーパスを読んで順に渡して実行します。全ページのシグナル(URL パス・スタイルシート・ホスト)を渡してブロック分け(Pass 0)し、続けて全ページの HTML をコーパス順に渡します。計算する呼び出しはアドオン内のスレッドプールで動き、Promise を返します。呼び出しは重ねず、1 つずつ await します。
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
103
|
import { createTemplateClassificationRun } from '@nitpicker/core/create-template-classification-run';
|
|
@@ -117,25 +117,25 @@ const { keys, keyOfPage, reasons } = await run.takeOutput();
|
|
|
117
117
|
keys[keyOfPage[0]!]; // '["path:news","cluster:0"]'
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
ブロックは既定で全ページをクラスタリングします。次の 2
|
|
120
|
+
ブロックは既定で全ページをクラスタリングします。次の 2 つの場合だけ、そのブロックを`TEMPLATE_BLOCK_SAMPLE_SIZE`(`@nitpicker/core/template-block-sample-size`)ページのサンプルでクラスタリングします。
|
|
121
121
|
|
|
122
|
-
- Stage A の類似度表(`n * (n - 1) / 2 * 8
|
|
123
|
-
-
|
|
122
|
+
- Stage A の類似度表(`n * (n - 1) / 2 * 8`バイト、`n`はブロックのページ数)が`memoryBudget`を超える。`memoryBudget`は`createTemplateClassificationRun`のオプションで、既定は`TEMPLATE_MEMORY_BUDGET`(`@nitpicker/core/template-memory-budget`、512 MiB)、0 なら全ブロックが対象になる。
|
|
123
|
+
- 全ページで計算するブロックの合計が`TEMPLATE_EXACT_PAGE_LIMIT`(`@nitpicker/core/template-exact-page-limit`、20,000 ページ)を超える。この場合は、標本より大きい(100 ページを超える)ブロックを、ページ数が多い順(同数なら出現順)に、収まるまで対象にする。100 ページ以下のブロックはサンプルにしても保持ページが減らないので対象にならず、それだけで上限を超えるときは超えたまま保持する。上限は固定で、利用者は変えられない。
|
|
124
124
|
|
|
125
|
-
既定の 512 MiB は、約 11,500 ページのブロックまでの類似度表に当たります。1 ページの解析結果は最大で約 60 KB です。同じ切り取りの深さはトークンを共有し、本文は圧縮して持つので、通常はこれより小さくなります。20,000 ページなら最大で約 1.2 GB
|
|
125
|
+
既定の 512 MiB は、約 11,500 ページのブロックまでの類似度表に当たります。1 ページの解析結果は最大で約 60 KB です。同じ切り取りの深さはトークンを共有し、本文は圧縮して持つので、通常はこれより小さくなります。20,000 ページなら最大で約 1.2 GB を、ブロックの計算が終わるまで抱えます。どのブロックが落ちるかで保存される`templateKey`が決まるので、メモリ上限を変えると結果が変わります。既存のアーカイブは、`viewer-build`で再分類するまで以前のキーのままです。
|
|
126
126
|
|
|
127
|
-
サンプルに落としたブロックの残りのページは、2 回目の読み込み(`needsAssignment()
|
|
127
|
+
サンプルに落としたブロックの残りのページは、2 回目の読み込み(`needsAssignment()`が true のときの`pushAssignmentPages`)で最も近いクラスタに割り当てます。落としたブロックは、`block()`の間に`block-sampled`の進捗イベントで 1 つずつ通知され、`takeOutput()`の`sampledBlocks`にも、理由(`table-over-budget`か`pages-over-limit`)つきで残ります。どちらの読み込みでも全ページをコーパス順に渡しますが、`pageMask()`が 0 のページは HTML を空文字にして構いません(HTML を読み出す必要もありません)。
|
|
128
128
|
|
|
129
129
|
### スレッドプール・同時実行数・キャンセル
|
|
130
130
|
|
|
131
131
|
非同期のネイティブ呼び出し(`matchSelectorSnapshots`・`searchHtmlSnapshots`・テンプレート分類の各呼び出し)は、アドオンが持つ専用のスレッドプールで動きます。次の 2 つの環境変数で調整できます。値は正の整数で、プロセスで最初にプールを使うときに 1 回だけ読みます。正の整数でない値は、既定値に置き換えずにエラーにします。
|
|
132
132
|
|
|
133
|
-
| 環境変数 | 既定 | 内容
|
|
134
|
-
| ------------------------------ | ------------------------------------------------------- |
|
|
135
|
-
| `NITPICKER_NATIVE_THREADS` | rayon の既定(`RAYON_NUM_THREADS`、なければ論理コア数) |
|
|
136
|
-
| `NITPICKER_NATIVE_CONCURRENCY` | 1 | 同時に走らせる非同期呼び出しの数。1
|
|
133
|
+
| 環境変数 | 既定 | 内容 |
|
|
134
|
+
| ------------------------------ | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
135
|
+
| `NITPICKER_NATIVE_THREADS` | rayon の既定(`RAYON_NUM_THREADS`、なければ論理コア数) | プールのスレッド数。同期の`computeUrlSortRanks`もこのプールで動く |
|
|
136
|
+
| `NITPICKER_NATIVE_CONCURRENCY` | 1 | 同時に走らせる非同期呼び出しの数。1 つの呼び出しがすでに全スレッドを使うので、増やしても合計の処理量は増えない。同期の`computeUrlSortRanks`はこの上限に数えず、待たずに専用プールを使う |
|
|
137
137
|
|
|
138
|
-
上限を超えた呼び出しは、拒否せず、受け付けた順(FIFO)に待ちます。待っている間はスレッドを占有しません。`checkNativeExecutorConfig
|
|
138
|
+
上限を超えた呼び出しは、拒否せず、受け付けた順(FIFO)に待ちます。待っている間はスレッドを占有しません。`checkNativeExecutorConfig`は、環境変数の誤りを最初のネイティブ呼び出しではなく作業の開始前に検出します。
|
|
139
139
|
|
|
140
140
|
```ts
|
|
141
141
|
import { checkNativeExecutorConfig } from '@nitpicker/core/check-native-executor-config';
|
|
@@ -143,7 +143,7 @@ import { checkNativeExecutorConfig } from '@nitpicker/core/check-native-executor
|
|
|
143
143
|
checkNativeExecutorConfig(); // NITPICKER_NATIVE_THREADS="lots" なら InvalidArg で投げる
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
`matchSelectorSnapshots
|
|
146
|
+
`matchSelectorSnapshots`と`searchHtmlSnapshots`は`signal`(`AbortSignal`)を受け取ります。abort すると、実行中の呼び出しは次のスナップショットの前か展開中のスナップショットの次の 1 MiB を読む前で止まり、待機中の呼び出しは順番が来た時点で終わります。どちらも`signal.reason`で reject します。すでに abort 済みの signal は、アドオンを呼ばずに reject します。同じバッチに展開に失敗したスナップショットがあっても、abort を見たスナップショットが 1 つでもあれば abort(`signal.reason`)を返します。展開のエラーを返すのは、どのスナップショットも abort を見る前に失敗したときだけです。テンプレート分類は、これまでどおり`run.cancel()`で止めます。
|
|
147
147
|
|
|
148
148
|
```ts
|
|
149
149
|
const controller = new AbortController();
|
|
@@ -154,20 +154,20 @@ await pending; // rejects with the Error above
|
|
|
154
154
|
|
|
155
155
|
## 開発
|
|
156
156
|
|
|
157
|
-
Rust
|
|
158
|
-
|
|
159
|
-
- Rust
|
|
160
|
-
- `yarn test:rust
|
|
161
|
-
- body hash は既存アーカイブに保存済みの値と byte 単位で一致させています(例外は、本物の body
|
|
162
|
-
- 構造シグナルの技術検出(`crates/nitpicker_tech_detect
|
|
163
|
-
- テンプレート分類(`crates/nitpicker_template_cluster
|
|
164
|
-
- URL の順序(`crates/nitpicker_url_key`)は、文字列から数値を取り出して 2 件ずつ比べる方式を採りません。その方式は推移律が崩れる(`a9
|
|
165
|
-
- alias キー(`crates/nitpicker_url_key
|
|
166
|
-
- 連結成分(`crates/nitpicker_union_find`)の成分は、辺の順序とバッチ分割に依存しません(`tests/components_properties.rs`)。成分の番号は候補の並び順だけで決まり、read model
|
|
167
|
-
- セレクタ照合(`crates/nitpicker_html_scan
|
|
168
|
-
- `crates/nitpicker_html_parser
|
|
169
|
-
-
|
|
170
|
-
-
|
|
157
|
+
Rust ツールチェーンが必要です(バージョンはリポジトリルートの`rust-toolchain.toml`で固定。セットアップは[CONTRIBUTING.md](../../../CONTRIBUTING.md)を参照)。`yarn build`を実行すると、`scripts/build-native.mjs`がホスト向けのアドオンをビルドしてパッケージ直下に`core.<platform>.node`として置きます。ローダーはこのローカルビルドを先に探し、なければプラットフォーム別パッケージを読み込みます。
|
|
158
|
+
|
|
159
|
+
- Rust のコードは`crates/`配下の Cargo workspace にあります。napi に依存するのは`nitpicker_napi`(公開関数だけの薄い層)だけで、計算本体の crate は`cargo test`だけでテストできます
|
|
160
|
+
- `yarn test:rust`で Rust のテスト、`yarn lint`で rustfmt と clippy も実行します
|
|
161
|
+
- body hash は既存アーカイブに保存済みの値と byte 単位で一致させています(例外は、本物の body より前に`<bodyguard>`のような`<body`で始まるカスタム要素があるページで、body の開始位置が変わるため値が変わります。#434)。`crates/nitpicker_html_scan/tests/fixtures/body-hash-golden.json`は`@nitpicker/archive`の`src/body-hash/`にある JavaScript 段階実装(parity テストの oracle)から生成した golden fixture です。Rust 側は正規化とマスクを 1 パスにまとめていて、段階版の Rust 関数と一致することを`tests/fused_body_hash_properties.rs`で確かめています
|
|
162
|
+
- 構造シグナルの技術検出(`crates/nitpicker_tech_detect`)は、既存アーカイブの`technology_signals`を書いた JavaScript 正規表現と同じシグナル・同じ順序・同じ evidence を返します。正規表現は JS の`u`フラグなしの意味論に合わせ、`\s`は JS が含める非 ASCII の空白(U+00A0・U+FEFF など)まで並べています。走査は、定義ごとの必須リテラルを Aho-Corasick で 1 回探し、見つかった定義だけを正規表現で確かめます。`tests/fixtures/technology-signals-golden.json`は`@nitpicker/archive`の`src/meta/technologies/structural-signal-definitions.ts`(parity テストの oracle)から`scripts/generate-technology-signals-golden.mjs`で生成した golden fixture です
|
|
163
|
+
- テンプレート分類(`crates/nitpicker_template_cluster`)も、既存アーカイブの`templateKey`と reason に一致させています。HTML は htmlparser2 12.0.0 の挙動を移植した`crates/nitpicker_html_parser`で読み、スタイルシートのホストは呼び出し側の`new URL(href).host`を使います。一致の確認は`@nitpicker/archive`の golden(`src/template-classification/golden/`)で行います
|
|
164
|
+
- URL の順序(`crates/nitpicker_url_key`)は、文字列から数値を取り出して 2 件ずつ比べる方式を採りません。その方式は推移律が崩れる(`a9`は`a10`より前、`a10`は`a1x`より前、`a1x`は`a9`より前になる)ためで、順序はバイト列キーの全順序として定義します。基準は、`tests/order_spec.rs`(期待順序の表)と`tests/order_properties.rs`(入力順不変・キーが同じ URL は生の URL 文字列の順・数値順などのプロパティテスト)です。順位は viewer の read model に保存されるので、順序の定義を変えるときは read model の schema version を上げます
|
|
165
|
+
- alias キー(`crates/nitpicker_url_key`の`alias_keys`)は、既存アーカイブの`content_items.alias_of_id`を作った JavaScript 実装のキーと一致させています。`tests/fixtures/alias-keys-golden.json`は`@nitpicker/archive`の`src/url-alias/`にある JavaScript 実装(parity テストの oracle)から`scripts/generate-alias-keys-golden.mjs`で生成した golden fixture で、キーは URL を書かれたまま(WHATWG URL の`pathname`と`search`)読むので、並べ替え用のキーとは別の読み方です。グルーピングと代表選定は、JavaScript の参照実装と突き合わせる parity テスト(`@nitpicker/archive`の`group-alias-candidates.parity.spec.ts`)で固めています
|
|
166
|
+
- 連結成分(`crates/nitpicker_union_find`)の成分は、辺の順序とバッチ分割に依存しません(`tests/components_properties.rs`)。成分の番号は候補の並び順だけで決まり、read model の`component_id`になるので、候補は page id の昇順で渡します
|
|
167
|
+
- セレクタ照合(`crates/nitpicker_html_scan`の`html_matches_selector`と`scan_snapshots`)の結果は永続化されないので、`docs/query.md`の解釈規則を正解にして書いています。`tag_tokenizer.rs`がタグを読み、direct 段(`run_direct_match.rs`)と開タグスタック(`run_selector_state_machine.rs`)が同じトークナイザを使います。開始タグの属性は、ブラウザのシリアライザの出力を読み戻せるよう HTML のトークナイザと同じ規則で読みます(`start_tag_attributes.rs`。ソースの引用符が欠けたページは属性名に`"`を含んで直列化されるため、引用符の対応だけでは開始タグの終わりを見失います)。正解は`@nitpicker/query`の oracle spec(直列化前の DOM の`querySelector`)です
|
|
168
|
+
- `crates/nitpicker_html_parser`には生成した固定データが 2 つあります。どちらも、リポジトリが依存していない固定版のパッケージを scratch ディレクトリに入れ、そのディレクトリを引数に渡して生成します(手順と理由は各スクリプトの冒頭)
|
|
169
|
+
- エンティティの表`src/html_decode_tree.rs`: `node scripts/generate-html-decode-tree.mjs <entities@8.0.0 のディレクトリ>`。デコードを意図して変えるときだけ再生成します
|
|
170
|
+
- パーサーの比較基準`tests/htmlparser2-fixture-events.tsv`: `node scripts/record-htmlparser2-events.mjs <htmlparser2@12.0.0 のディレクトリ>`。`@nitpicker/archive`の`page-cluster/__fixtures__/`を変えたときに取り直します
|
|
171
171
|
|
|
172
172
|
## 関連リンク
|
|
173
173
|
|
package/lib/to-u32-ids.js
CHANGED
|
@@ -15,7 +15,6 @@ import { assertU32Id } from './assert-u32-id.js';
|
|
|
15
15
|
export function toU32Ids(values, what) {
|
|
16
16
|
const ids = new Uint32Array(values.length);
|
|
17
17
|
// `ArrayLike` has no iterator, so an index loop is the way to read it.
|
|
18
|
-
// eslint-disable-next-line unicorn/no-for-loop
|
|
19
18
|
for (let index = 0; index < values.length; index++) {
|
|
20
19
|
ids[index] = assertU32Id(values[index], what);
|
|
21
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitpicker/core",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.1",
|
|
4
4
|
"description": "Native (Rust, Node-API) compute core for Nitpicker",
|
|
5
5
|
"author": "D-ZERO",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -102,8 +102,8 @@
|
|
|
102
102
|
"clean": "node scripts/build-native.mjs --clean && tsc --build --clean"
|
|
103
103
|
},
|
|
104
104
|
"optionalDependencies": {
|
|
105
|
-
"@nitpicker/core-darwin-arm64": "0.25.
|
|
106
|
-
"@nitpicker/core-linux-x64-gnu": "0.25.
|
|
105
|
+
"@nitpicker/core-darwin-arm64": "0.25.1",
|
|
106
|
+
"@nitpicker/core-linux-x64-gnu": "0.25.1"
|
|
107
107
|
},
|
|
108
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "fa839178ea8f40e92fc742e0480c6cfbbb8fb01f"
|
|
109
109
|
}
|