livedesk 0.1.459 → 0.1.461

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.
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { cpSync, existsSync, mkdirSync, readFileSync, rmSync } from 'node:fs';
4
+ import { dirname, isAbsolute, relative, resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const packageRoot = resolve(__dirname, '..');
9
+ const repoRoot = resolve(packageRoot, '..', '..');
10
+ const sourceDist = resolve(repoRoot, 'apps', 'web', 'dist');
11
+ const targetDist = resolve(packageRoot, 'web', 'dist');
12
+ const sourceHub = resolve(repoRoot, 'packages', 'hub');
13
+ const targetHub = resolve(packageRoot, 'hub');
14
+ const sourceRuntimeCore = resolve(repoRoot, 'packages', 'runtime-core');
15
+ const targetRuntimeCore = resolve(packageRoot, 'runtime-core');
16
+ const sourceClient = resolve(repoRoot, 'packages', 'client');
17
+ const targetClient = resolve(packageRoot, 'client');
18
+ const sourceOnly = process.argv.includes('--source-only');
19
+ const FILE_LOCK_RETRY_LIMIT = 40;
20
+ const FILE_LOCK_RETRY_DELAY_MS = 250;
21
+ const monorepoSourceAssets = [
22
+ ['Hub source', resolve(sourceHub, 'src', 'server.js')],
23
+ ['Hub manifest', resolve(sourceHub, 'package.json')],
24
+ ['runtime core source', resolve(sourceRuntimeCore, 'src', 'index.js')],
25
+ ['runtime core manifest', resolve(sourceRuntimeCore, 'package.json')],
26
+ ['Client source', resolve(sourceClient, 'bin', 'livedesk-client.js')],
27
+ ['Client manifest', resolve(sourceClient, 'package.json')]
28
+ ];
29
+ const packagedRuntimeAssets = [
30
+ ['web UI', resolve(targetDist, 'index.html')],
31
+ ['Hub source', resolve(targetHub, 'src', 'server.js')],
32
+ ['Hub remote bridge', resolve(targetHub, 'src', 'remote-hub.js')],
33
+ ['Hub manifest', resolve(targetHub, 'package.json')],
34
+ ['runtime core source', resolve(targetRuntimeCore, 'src', 'index.js')],
35
+ ['runtime core manifest', resolve(targetRuntimeCore, 'package.json')],
36
+ ['Client launcher', resolve(targetClient, 'bin', 'livedesk-client.js')],
37
+ ['Client runtime', resolve(targetClient, 'src', 'runtime', 'client-runtime-server.js')],
38
+ ['Client version test', resolve(targetClient, 'tests', 'client-version.test.mjs')],
39
+ ['Client manifest', resolve(targetClient, 'package.json')]
40
+ ];
41
+
42
+ function waitForFileLock(milliseconds) {
43
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
44
+ }
45
+
46
+ function isTransientFileLock(error) {
47
+ return ['EBUSY', 'EPERM', 'ENOTEMPTY'].includes(String(error?.code || ''));
48
+ }
49
+
50
+ function replaceDirectory(source, target, options = {}) {
51
+ for (let attempt = 0; attempt <= FILE_LOCK_RETRY_LIMIT; attempt += 1) {
52
+ try {
53
+ rmSync(target, { recursive: true, force: true });
54
+ mkdirSync(target, { recursive: true });
55
+ cpSync(source, target, { recursive: true, ...options });
56
+ return;
57
+ } catch (error) {
58
+ if (!isTransientFileLock(error) || attempt === FILE_LOCK_RETRY_LIMIT) throw error;
59
+ console.warn(`Waiting for a temporary file lock while syncing ${target} (${String(error.code)}; retry ${attempt + 1}/${FILE_LOCK_RETRY_LIMIT}).`);
60
+ waitForFileLock(FILE_LOCK_RETRY_DELAY_MS);
61
+ }
62
+ }
63
+ }
64
+
65
+ function shouldCopyThinClientPath(sourcePath) {
66
+ const clientRelativePath = relative(sourceClient, resolve(sourcePath));
67
+ if (!clientRelativePath || clientRelativePath === '.') return true;
68
+ if (isAbsolute(clientRelativePath) || clientRelativePath.startsWith('..')) return true;
69
+ const [topLevelDirectory] = clientRelativePath.split(/[\\/]/);
70
+ return topLevelDirectory.toLowerCase() !== 'fast';
71
+ }
72
+
73
+ function missingAssets(assets) {
74
+ return assets.filter(([, assetPath]) => !existsSync(assetPath)).map(([label]) => label);
75
+ }
76
+
77
+ function isLiveDeskMonorepo() {
78
+ try {
79
+ const manifest = JSON.parse(readFileSync(resolve(repoRoot, 'package.json'), 'utf8'));
80
+ return manifest?.name === 'livedesk-react';
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
85
+
86
+ function validateInstalledPackage() {
87
+ const missing = missingAssets(packagedRuntimeAssets);
88
+ if (missing.length > 0) {
89
+ throw new Error(
90
+ `LiveDesk monorepo sources are unavailable and packaged assets are incomplete: ${missing.join(', ')}.`);
91
+ }
92
+ if (existsSync(resolve(targetClient, 'fast'))) {
93
+ throw new Error(
94
+ 'LiveDesk packaged Client is not thin: embedded client/fast payload must be removed.');
95
+ }
96
+ }
97
+
98
+ const liveDeskMonorepo = isLiveDeskMonorepo();
99
+ const missingMonorepoSources = missingAssets(monorepoSourceAssets);
100
+ if (!liveDeskMonorepo) {
101
+ validateInstalledPackage();
102
+ console.log('Validated existing LiveDesk packaged assets; monorepo synchronization is not required.');
103
+ } else {
104
+ if (missingMonorepoSources.length > 0) {
105
+ throw new Error(
106
+ `LiveDesk monorepo sources are incomplete: ${missingMonorepoSources.join(', ')}.`);
107
+ }
108
+ if (!sourceOnly && !existsSync(resolve(sourceDist, 'index.html'))) {
109
+ throw new Error(`LiveDesk web build not found at ${sourceDist}. Run npm run build -w @livedesk/web first.`);
110
+ }
111
+
112
+ if (!sourceOnly) {
113
+ replaceDirectory(sourceDist, targetDist);
114
+ }
115
+
116
+ replaceDirectory(resolve(sourceHub, 'src'), resolve(targetHub, 'src'));
117
+ cpSync(resolve(sourceHub, 'package.json'), resolve(targetHub, 'package.json'));
118
+ replaceDirectory(resolve(sourceRuntimeCore, 'src'), resolve(targetRuntimeCore, 'src'));
119
+ cpSync(resolve(sourceRuntimeCore, 'package.json'), resolve(targetRuntimeCore, 'package.json'));
120
+ replaceDirectory(sourceClient, targetClient, { filter: shouldCopyThinClientPath });
121
+ if (!sourceOnly) {
122
+ console.log(`Copied LiveDesk web assets to ${targetDist}`);
123
+ }
124
+ console.log(`Copied LiveDesk hub assets to ${targetHub}`);
125
+ console.log(`Copied LiveDesk runtime core to ${targetRuntimeCore}`);
126
+ console.log(`Copied thin LiveDesk client runtime to ${targetClient}; RemoteFast is installed from the matching optional platform package.`);
127
+ }