freertc 0.1.2 → 0.1.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/bin/freertc.mjs CHANGED
@@ -34,7 +34,7 @@ Examples:
34
34
 
35
35
  function runInProject(command, args, { bootstrap = false } = {}) {
36
36
  if (bootstrap) {
37
- ensureProjectFiles(PROJECT_ROOT);
37
+ ensureProjectFiles(PROJECT_ROOT, { updateExisting: true });
38
38
  }
39
39
 
40
40
  const result = spawnSync(command, args, {
@@ -87,7 +87,7 @@ if (subcommand === 'init' || subcommand === 'install') {
87
87
  }
88
88
 
89
89
  if (subcommand === 'deploy') {
90
- ensureProjectFiles(PROJECT_ROOT);
90
+ ensureProjectFiles(PROJECT_ROOT, { updateExisting: true });
91
91
  requireWranglerConfig();
92
92
  const wrangler = resolveWranglerCommand(PROJECT_ROOT);
93
93
  runInProject(wrangler.command, [...wrangler.baseArgs, 'deploy', '--env', 'production', ...rest]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freertc",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Cloudflare Worker signaling relay for WebRTC peers with D1 storage.",
5
5
  "keywords": [
6
6
  "webrtc",
@@ -59,28 +59,42 @@ export function resolveProjectRoot(startDir = process.cwd()) {
59
59
  );
60
60
  }
61
61
 
62
- export function ensureProjectFiles(projectRoot) {
62
+ function filesMatch(sourcePath, targetPath) {
63
+ if (!fs.existsSync(sourcePath) || !fs.existsSync(targetPath)) {
64
+ return false;
65
+ }
66
+
67
+ const source = fs.readFileSync(sourcePath);
68
+ const target = fs.readFileSync(targetPath);
69
+ return source.equals(target);
70
+ }
71
+
72
+ export function ensureProjectFiles(projectRoot, { updateExisting = false } = {}) {
63
73
  const targetRoot = path.resolve(projectRoot);
64
74
  if (targetRoot === PACKAGE_ROOT) {
65
75
  return [];
66
76
  }
67
77
 
68
- const copied = [];
78
+ const synced = [];
69
79
 
70
80
  for (const [sourceRelativePath, targetRelativePath] of PROJECT_FILE_MAPPINGS) {
71
81
  const sourcePath = path.join(PACKAGE_ROOT, sourceRelativePath);
72
82
  const targetPath = path.join(targetRoot, targetRelativePath);
73
83
 
74
- if (fs.existsSync(targetPath) || !fs.existsSync(sourcePath)) {
84
+ if (!fs.existsSync(sourcePath)) {
85
+ continue;
86
+ }
87
+
88
+ if (fs.existsSync(targetPath) && (!updateExisting || filesMatch(sourcePath, targetPath))) {
75
89
  continue;
76
90
  }
77
91
 
78
92
  fs.mkdirSync(path.dirname(targetPath), { recursive: true });
79
93
  fs.copyFileSync(sourcePath, targetPath);
80
- copied.push(targetRelativePath);
94
+ synced.push(targetRelativePath);
81
95
  }
82
96
 
83
- return copied;
97
+ return synced;
84
98
  }
85
99
 
86
100
  export function resolveWranglerCommand(cwd = process.cwd()) {
@@ -402,7 +402,7 @@ async function main() {
402
402
  const forcedMode = modeFromArgs(process.argv);
403
403
 
404
404
  try {
405
- const copiedFiles = ensureProjectFiles(ROOT);
405
+ const copiedFiles = ensureProjectFiles(ROOT, { updateExisting: true });
406
406
 
407
407
  console.log(`\n${PROJECT_NAME} Wrangler Install Wizard\n`);
408
408
  console.log(`Using project root: ${ROOT}`);
@@ -416,7 +416,7 @@ async function main() {
416
416
  }
417
417
 
418
418
  if (copiedFiles.length > 0) {
419
- console.log('Copied package files into this project:');
419
+ console.log('Synced package-managed files into this project:');
420
420
  for (const file of copiedFiles) {
421
421
  console.log(` - ${file}`);
422
422
  }
@@ -447,7 +447,7 @@ async function main() {
447
447
  if (copiedFiles.length === 0) {
448
448
  console.log('Required worker files already exist in this project.');
449
449
  } else {
450
- console.log('Project bootstrapped from the published freertc package.');
450
+ console.log('Project files refreshed from the published freertc package.');
451
451
  }
452
452
 
453
453
  resolveWrangler();
package/src/index.js CHANGED
@@ -227,15 +227,29 @@ async function forwardToRelay(relayUrl, message, selfRelayId) {
227
227
  const ws = resp.webSocket;
228
228
  ws.accept();
229
229
 
230
- // Outbound Worker WebSocket: send immediately after accept(), no open event needed
231
- const relayPeerId = selfRelayId || "relay-bridge";
232
- ws.send(JSON.stringify({
233
- psp_version: PSP_VERSION, type: "announce", network: message.network,
234
- from: relayPeerId, message_id: crypto.randomUUID(),
235
- timestamp: Date.now(), ttl_ms: 10_000, body: { capabilities: { relay: true } }
236
- }));
237
- ws.send(JSON.stringify(message));
238
- ws.close();
230
+ await new Promise((resolve) => {
231
+ const relayPeerId = selfRelayId || "relay-bridge";
232
+ const closeTimer = setTimeout(() => {
233
+ try { ws.close(); } catch {}
234
+ resolve();
235
+ }, 250);
236
+
237
+ const finish = () => {
238
+ clearTimeout(closeTimer);
239
+ resolve();
240
+ };
241
+
242
+ ws.addEventListener("error", finish, { once: true });
243
+ ws.addEventListener("close", finish, { once: true });
244
+
245
+ // Outbound Worker WebSocket: send immediately after accept(), no open event needed.
246
+ ws.send(JSON.stringify({
247
+ psp_version: PSP_VERSION, type: "announce", network: message.network,
248
+ from: relayPeerId, message_id: crypto.randomUUID(),
249
+ timestamp: Date.now(), ttl_ms: 10_000, body: { capabilities: { relay: true } }
250
+ }));
251
+ ws.send(JSON.stringify(message));
252
+ });
239
253
  } catch {}
240
254
  }
241
255