@kubohiroya/turbowarp-webrtc-qrcode-pairing 0.2.0 → 0.2.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.ja.md CHANGED
@@ -15,7 +15,7 @@ QRコードを使ってWebRTCの接続情報を交換するTurboWarp拡張です
15
15
  - Answerがどの Offer への応答かを追跡し、2台のカメラ側端末の接続情報が入れ替わらないようにします。
16
16
  - 搬送の進捗と接続状態を別々の状態として報告します。エラー、取消、再試行、期限にも対応します。
17
17
 
18
- `0.2.0`では、メッセージを連結QRコードで運び、1枚のQRを既定でOfferはversion 15、Answerはversion 20までに抑え、読んだペアリング用のQRをすべて報告します。`turbowarp-jsqr` 0.4.0以降が必要です。npmに公開済みなのは`0.1.0`です。
18
+ `0.2.0`では、メッセージを連結QRコードで運び、1枚のQRを既定でOfferはversion 15、Answerはversion 20までに抑え、読んだペアリング用のQRをすべて報告します。`turbowarp-jsqr` 0.4.0以降が必要です。`0.2.1`では、QRがカメラに写り続けている間の読取りがページの処理を止めてしまう不具合を直しました。
19
19
 
20
20
  > [!NOTE]
21
21
  > ペアリング用ブロックは起動時固定のフィーチャーフラグの内側にあり、既定は無効です。
package/README.md CHANGED
@@ -15,7 +15,7 @@ A TurboWarp extension for exchanging WebRTC connection information through QR co
15
15
  - Tracks which offer an answer replies to, so two camera machines never receive each other's connection.
16
16
  - Reports transport progress and connection state as separate states, plus errors, cancellation, retry and deadlines.
17
17
 
18
- Version 0.2.0 carries messages as Structured Append sequences, caps Offer codes at QR version 15 and Answer codes at 20, and reports every pairing code read. It needs `turbowarp-jsqr` 0.4.0 or later. 0.1.0 is the version published on npm.
18
+ Version 0.2.0 carries messages as Structured Append sequences, caps Offer codes at QR version 15 and Answer codes at 20, and reports every pairing code read. It needs `turbowarp-jsqr` 0.4.0 or later. 0.2.1 fixes a camera scan that starved the page while a code stayed in view.
19
19
 
20
20
  > [!NOTE]
21
21
  > The pairing blocks are behind a startup feature flag that is off by default. See
@@ -116,7 +116,7 @@ pnpm run dev
116
116
 
117
117
  Build output: `dist/webrtc-qrcode-pairing.js` and `dist/extension-manifest.json`. Load the JavaScript file as a custom TurboWarp extension. The manifest always records every declared block, including blocks the feature flag hides at runtime: it is the build-time contract, not the runtime state.
118
118
 
119
- Package name and version: `@kubohiroya/turbowarp-webrtc-qrcode-pairing@0.2.0` (0.1.0 is the latest published on npm).
119
+ Package name and version: `@kubohiroya/turbowarp-webrtc-qrcode-pairing@0.2.1`.
120
120
 
121
121
  ## Block reference
122
122
 
@@ -3207,6 +3207,7 @@
3207
3207
  this.runtime = runtime;
3208
3208
  this.owner = owner;
3209
3209
  this.leasedCameraId = "";
3210
+ this.nextReadAt = 0;
3210
3211
  }
3211
3212
  async scanOnce(options) {
3212
3213
  if (options.signal.aborted) throw cancelled();
@@ -3244,6 +3245,7 @@
3244
3245
  }
3245
3246
  if (settled) return;
3246
3247
  if (read !== null) {
3248
+ this.nextReadAt = Date.now() + interval;
3247
3249
  cleanup();
3248
3250
  resolve(read);
3249
3251
  return;
@@ -3251,7 +3253,7 @@
3251
3253
  timer = setTimeout(() => void tick(), interval);
3252
3254
  };
3253
3255
  options.signal.addEventListener("abort", onAbort, { once: true });
3254
- tick();
3256
+ timer = setTimeout(() => void tick(), Math.max(0, this.nextReadAt - Date.now()));
3255
3257
  });
3256
3258
  }
3257
3259
  async release() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubohiroya/turbowarp-webrtc-qrcode-pairing",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "TurboWarp extension that pairs WebRTC peers by carrying offers and answers as QR codes.",
5
5
  "author": "Hiroya Kubo <hiroya@cuc.ac.jp>",
6
6
  "license": "MPL-2.0",
@@ -66,6 +66,15 @@ export interface QrScanPort {
66
66
  export class CameraQrScanner implements QrScanPort {
67
67
  private lease: CameraLease | undefined;
68
68
  private leasedCameraId = '';
69
+ /**
70
+ * Wall-clock time before which the next frame is not read.
71
+ *
72
+ * A code left in front of the camera reads on every frame, and a sequence is read code after
73
+ * code, so the caller asks again at once. Without a pause between reads the loop would run on
74
+ * promise callbacks alone and never give the page its turn: no redraw, no Scratch thread, no
75
+ * timer. Every read therefore waits for the poll interval after the one before it.
76
+ */
77
+ private nextReadAt = 0;
69
78
 
70
79
  public constructor(
71
80
  private readonly runtime: TurboWarpRuntime,
@@ -118,6 +127,7 @@ export class CameraQrScanner implements QrScanPort {
118
127
  // Aborted while the frame was decoding: the abort handler already rejected.
119
128
  if (settled) return;
120
129
  if (read !== null) {
130
+ this.nextReadAt = Date.now() + interval;
121
131
  cleanup();
122
132
  resolve(read);
123
133
  return;
@@ -125,7 +135,9 @@ export class CameraQrScanner implements QrScanPort {
125
135
  timer = setTimeout(() => void tick(), interval);
126
136
  };
127
137
  options.signal.addEventListener('abort', onAbort, {once: true});
128
- void tick();
138
+ // Always through a timer, even when no wait is due, so a read never follows the previous
139
+ // one within the same turn of the event loop.
140
+ timer = setTimeout(() => void tick(), Math.max(0, this.nextReadAt - Date.now()));
129
141
  });
130
142
  }
131
143