javascript-solid-server 0.0.85 → 0.0.86

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.
@@ -323,7 +323,8 @@
323
323
  "Bash(npm exec serve:*)",
324
324
  "Bash(npm link)",
325
325
  "Bash(npm link:*)",
326
- "Bash(git push)"
326
+ "Bash(git push)",
327
+ "Bash(ulimit:*)"
327
328
  ]
328
329
  }
329
330
  }
package/bin/jss.js CHANGED
@@ -105,6 +105,8 @@ program
105
105
 
106
106
  // Create and start server
107
107
  const server = createServer({
108
+ port: config.port,
109
+ host: config.host,
108
110
  logger: config.logger,
109
111
  conneg: config.conneg,
110
112
  notifications: config.notifications,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "javascript-solid-server",
3
- "version": "0.0.85",
3
+ "version": "0.0.86",
4
4
  "description": "A minimal, fast Solid server",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -40,6 +40,7 @@ export function handleWebSocket(socket, request, webId = null) {
40
40
  // Store webId and server info on socket for ACL checks
41
41
  socket.webId = webId;
42
42
  socket.serverOrigin = `${request.protocol}://${request.hostname}`;
43
+ socket.publicMode = request.config?.public || false;
43
44
 
44
45
  // Send protocol greeting
45
46
  socket.send('protocol solid-0.1');
@@ -123,6 +124,11 @@ async function checkSubscriptionAccess(url, socket) {
123
124
  const stats = await storage.stat(resourcePath);
124
125
  const isContainer = stats?.isDirectory || resourcePath.endsWith('/');
125
126
 
127
+ // Skip WAC check in public mode
128
+ if (socket.publicMode) {
129
+ return true;
130
+ }
131
+
126
132
  // Check WAC read permission
127
133
  const { allowed } = await checkAccess({
128
134
  resourceUrl: url,
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Live Reload Test
3
+ *
4
+ * Tests the full chain: file change → WebSocket pub → client receives
5
+ */
6
+
7
+ import { createServer } from '../src/server.js';
8
+ import { writeFileSync, mkdirSync, rmSync, existsSync } from 'fs';
9
+ import { join } from 'path';
10
+ import WebSocket from 'ws';
11
+
12
+ const TEST_PORT = 9876;
13
+ const TEST_DIR = '/tmp/live-reload-test-suite';
14
+ const BASE_URL = `http://localhost:${TEST_PORT}`;
15
+
16
+ // Setup and teardown
17
+ function setupTestDir() {
18
+ if (existsSync(TEST_DIR)) {
19
+ rmSync(TEST_DIR, { recursive: true });
20
+ }
21
+ mkdirSync(TEST_DIR, { recursive: true });
22
+ writeFileSync(join(TEST_DIR, 'index.html'), '<!DOCTYPE html><html><body>Hello</body></html>');
23
+ writeFileSync(join(TEST_DIR, 'test.txt'), 'initial content');
24
+ }
25
+
26
+ function cleanupTestDir() {
27
+ if (existsSync(TEST_DIR)) {
28
+ rmSync(TEST_DIR, { recursive: true });
29
+ }
30
+ }
31
+
32
+ // Test 1: Verify WebSocket notifications work for HTTP PUT
33
+ async function testHttpPutNotification() {
34
+ console.log('\n=== Test 1: HTTP PUT triggers WebSocket notification ===');
35
+
36
+ setupTestDir();
37
+
38
+ const server = createServer({
39
+ root: TEST_DIR,
40
+ port: TEST_PORT,
41
+ logger: false,
42
+ liveReload: true,
43
+ public: true,
44
+ });
45
+
46
+ await server.listen({ port: TEST_PORT, host: '0.0.0.0' });
47
+ console.log('Server started on port', TEST_PORT);
48
+
49
+ return new Promise((resolve, reject) => {
50
+ const timeout = setTimeout(() => {
51
+ ws.close();
52
+ server.close();
53
+ reject(new Error('Timeout: No WebSocket notification received'));
54
+ }, 5000);
55
+
56
+ const ws = new WebSocket(`ws://localhost:${TEST_PORT}/.notifications`);
57
+
58
+ ws.on('open', () => {
59
+ console.log('WebSocket connected');
60
+ // Subscribe to the test file
61
+ ws.send(`sub ${BASE_URL}/test.txt`);
62
+ console.log('Subscribed to', `${BASE_URL}/test.txt`);
63
+
64
+ // Wait a bit then do HTTP PUT
65
+ setTimeout(async () => {
66
+ console.log('Doing HTTP PUT...');
67
+ const res = await fetch(`${BASE_URL}/test.txt`, {
68
+ method: 'PUT',
69
+ body: 'updated via HTTP',
70
+ headers: { 'Content-Type': 'text/plain' }
71
+ });
72
+ console.log('PUT response:', res.status);
73
+ }, 500);
74
+ });
75
+
76
+ ws.on('message', (data) => {
77
+ const msg = data.toString();
78
+ console.log('WebSocket received:', msg);
79
+
80
+ if (msg.startsWith('pub ')) {
81
+ clearTimeout(timeout);
82
+ console.log('SUCCESS: Received pub notification');
83
+ ws.close();
84
+ server.close().then(() => {
85
+ cleanupTestDir();
86
+ resolve(true);
87
+ });
88
+ }
89
+ });
90
+
91
+ ws.on('error', (err) => {
92
+ clearTimeout(timeout);
93
+ server.close();
94
+ reject(err);
95
+ });
96
+ });
97
+ }
98
+
99
+ // Test 2: Verify file watcher detects filesystem changes
100
+ async function testFileWatcherNotification() {
101
+ console.log('\n=== Test 2: Filesystem change triggers WebSocket notification ===');
102
+
103
+ setupTestDir();
104
+
105
+ const server = createServer({
106
+ root: TEST_DIR,
107
+ port: TEST_PORT,
108
+ logger: false,
109
+ liveReload: true,
110
+ public: true,
111
+ });
112
+
113
+ await server.listen({ port: TEST_PORT, host: '0.0.0.0' });
114
+ console.log('Server started on port', TEST_PORT);
115
+
116
+ return new Promise((resolve, reject) => {
117
+ const timeout = setTimeout(() => {
118
+ ws.close();
119
+ server.close();
120
+ reject(new Error('Timeout: No WebSocket notification received for filesystem change'));
121
+ }, 5000);
122
+
123
+ const ws = new WebSocket(`ws://localhost:${TEST_PORT}/.notifications`);
124
+
125
+ ws.on('open', () => {
126
+ console.log('WebSocket connected');
127
+ // Subscribe to the test file
128
+ ws.send(`sub ${BASE_URL}/test.txt`);
129
+ console.log('Subscribed to', `${BASE_URL}/test.txt`);
130
+
131
+ // Wait a bit then modify file directly on filesystem
132
+ setTimeout(() => {
133
+ console.log('Modifying file via filesystem...');
134
+ writeFileSync(join(TEST_DIR, 'test.txt'), 'updated via filesystem ' + Date.now());
135
+ console.log('File written');
136
+ }, 1000);
137
+ });
138
+
139
+ ws.on('message', (data) => {
140
+ const msg = data.toString();
141
+ console.log('WebSocket received:', msg);
142
+
143
+ if (msg.startsWith('pub ')) {
144
+ clearTimeout(timeout);
145
+ console.log('SUCCESS: Received pub notification for filesystem change');
146
+ ws.close();
147
+ server.close().then(() => {
148
+ cleanupTestDir();
149
+ resolve(true);
150
+ });
151
+ }
152
+ });
153
+
154
+ ws.on('error', (err) => {
155
+ clearTimeout(timeout);
156
+ server.close();
157
+ reject(err);
158
+ });
159
+ });
160
+ }
161
+
162
+ // Test 3: Verify fs.watch works on this platform
163
+ async function testFsWatch() {
164
+ console.log('\n=== Test 3: Basic fs.watch functionality ===');
165
+
166
+ const { watch } = await import('fs');
167
+ const testFile = '/tmp/fswatch-test.txt';
168
+
169
+ writeFileSync(testFile, 'initial');
170
+
171
+ return new Promise((resolve, reject) => {
172
+ const timeout = setTimeout(() => {
173
+ watcher.close();
174
+ reject(new Error('fs.watch did not detect file change'));
175
+ }, 3000);
176
+
177
+ const watcher = watch(testFile, (eventType, filename) => {
178
+ console.log('fs.watch detected:', eventType, filename);
179
+ clearTimeout(timeout);
180
+ watcher.close();
181
+ resolve(true);
182
+ });
183
+
184
+ // Modify file after short delay
185
+ setTimeout(() => {
186
+ console.log('Modifying file...');
187
+ writeFileSync(testFile, 'modified ' + Date.now());
188
+ }, 500);
189
+ });
190
+ }
191
+
192
+ // Test 4: Verify fs.watch with recursive option
193
+ async function testFsWatchRecursive() {
194
+ console.log('\n=== Test 4: fs.watch with recursive option ===');
195
+
196
+ const { watch } = await import('fs');
197
+ const testDir = '/tmp/fswatch-recursive-test';
198
+
199
+ if (existsSync(testDir)) rmSync(testDir, { recursive: true });
200
+ mkdirSync(testDir, { recursive: true });
201
+ writeFileSync(join(testDir, 'file.txt'), 'initial');
202
+
203
+ return new Promise((resolve, reject) => {
204
+ const timeout = setTimeout(() => {
205
+ watcher.close();
206
+ console.log('FAIL: fs.watch recursive did not detect file change');
207
+ resolve(false); // Don't reject, just report failure
208
+ }, 3000);
209
+
210
+ let detected = false;
211
+ const watcher = watch(testDir, { recursive: true }, (eventType, filename) => {
212
+ if (!detected) {
213
+ detected = true;
214
+ console.log('fs.watch recursive detected:', eventType, filename);
215
+ clearTimeout(timeout);
216
+ watcher.close();
217
+ resolve(true);
218
+ }
219
+ });
220
+
221
+ watcher.on('error', (err) => {
222
+ console.log('fs.watch error:', err.message);
223
+ clearTimeout(timeout);
224
+ resolve(false);
225
+ });
226
+
227
+ // Modify file after short delay
228
+ setTimeout(() => {
229
+ console.log('Modifying file in watched directory...');
230
+ writeFileSync(join(testDir, 'file.txt'), 'modified ' + Date.now());
231
+ }, 500);
232
+ });
233
+ }
234
+
235
+ // Run all tests
236
+ async function runTests() {
237
+ console.log('Live Reload Test Suite');
238
+ console.log('======================');
239
+
240
+ try {
241
+ // Test basic fs.watch first
242
+ const fsWatchWorks = await testFsWatch();
243
+ console.log('Test 3 result: fs.watch works =', fsWatchWorks);
244
+
245
+ // Test recursive fs.watch
246
+ const fsWatchRecursiveWorks = await testFsWatchRecursive();
247
+ console.log('Test 4 result: fs.watch recursive works =', fsWatchRecursiveWorks);
248
+
249
+ // Test HTTP PUT notification
250
+ await testHttpPutNotification();
251
+ console.log('Test 1 result: PASSED');
252
+
253
+ // Test file watcher notification
254
+ await testFileWatcherNotification();
255
+ console.log('Test 2 result: PASSED');
256
+
257
+ console.log('\n=== All tests passed ===');
258
+ } catch (err) {
259
+ console.error('\n=== Test FAILED ===');
260
+ console.error(err.message);
261
+ process.exit(1);
262
+ }
263
+ }
264
+
265
+ runTests();