node-turbo 1.0.0 → 1.0.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 +245 -245
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ node-turbo has been tested with:
|
|
|
50
50
|
| Name | Version(s) |
|
|
51
51
|
| :--- | :--- |
|
|
52
52
|
| [Node.js](https://nodejs.org/) | 16.6 — 18.16.0 |
|
|
53
|
-
| [
|
|
53
|
+
| [Hotwire Turbo](https://turbo.hotwired.dev/) | 7.3.0 — 8.0.0-beta.2 |
|
|
54
54
|
| [Koa](https://koajs.com/) | 2.14.2 |
|
|
55
55
|
| [Express](https://expressjs.com/) | 4.18.2 |
|
|
56
56
|
| [ws](https://github.com/websockets/ws) | 8.15.1 |
|
|
@@ -67,10 +67,10 @@ See [`/docs/API.md`](./docs/API.md) for a documentation of all node-turbo classe
|
|
|
67
67
|
import { TurboStream } from 'node-turbo';
|
|
68
68
|
|
|
69
69
|
const ts = new TurboStream({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
action: 'append',
|
|
71
|
+
target: 'target-id'
|
|
72
|
+
},
|
|
73
|
+
'<p>My content</p>');
|
|
74
74
|
|
|
75
75
|
const html = ts.render();
|
|
76
76
|
```
|
|
@@ -79,9 +79,9 @@ This will render the following HTML fragment:
|
|
|
79
79
|
|
|
80
80
|
```html
|
|
81
81
|
<turbo-stream action="append" target="target-id">
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
<template>
|
|
83
|
+
<p>My content</p>
|
|
84
|
+
</template>
|
|
85
85
|
</turbo-stream>
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -91,9 +91,9 @@ For all [supported actions](https://turbo.hotwired.dev/handbook/streams#stream-m
|
|
|
91
91
|
import { TurboStream } from 'node-turbo';
|
|
92
92
|
|
|
93
93
|
const ts = new TurboStream()
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
.append('target-id', '<p>My content</p>')
|
|
95
|
+
.replace('target-id-2', '<p>New content</p>')
|
|
96
|
+
.remove('target-id-3');
|
|
97
97
|
const html = ts.render();
|
|
98
98
|
```
|
|
99
99
|
|
|
@@ -101,17 +101,17 @@ Result:
|
|
|
101
101
|
|
|
102
102
|
```html
|
|
103
103
|
<turbo-stream action="append" target="target-id">
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
<template>
|
|
105
|
+
<p>My content</p>
|
|
106
|
+
</template>
|
|
107
107
|
</turbo-stream>
|
|
108
108
|
<turbo-stream action="replace" target="target-id-2">
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
<template>
|
|
110
|
+
<p>New content</p>
|
|
111
|
+
</template>
|
|
112
112
|
</turbo-stream>
|
|
113
113
|
<turbo-stream action="remove" target="target-id-3">
|
|
114
|
-
|
|
114
|
+
<!-- <template> and content are omitted -->
|
|
115
115
|
</turbo-stream>
|
|
116
116
|
```
|
|
117
117
|
|
|
@@ -122,16 +122,16 @@ If you want to [target multiple elements](https://turbo.hotwired.dev/handbook/st
|
|
|
122
122
|
import { TurboStream } from 'node-turbo';
|
|
123
123
|
|
|
124
124
|
let ts = new TurboStream()
|
|
125
|
-
|
|
125
|
+
.appendAll('.my-targets', '<p>My content</p>');
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
Result:
|
|
129
129
|
|
|
130
130
|
```html
|
|
131
131
|
<turbo-stream action="append" targets=".my-targets">
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
<template>
|
|
133
|
+
<p>My content</p>
|
|
134
|
+
</template>
|
|
135
135
|
</turbo-stream>
|
|
136
136
|
```
|
|
137
137
|
|
|
@@ -141,7 +141,7 @@ If you want to use [custom actions](https://turbo.hotwired.dev/handbook/streams#
|
|
|
141
141
|
import { TurboStream } from 'node-turbo';
|
|
142
142
|
|
|
143
143
|
let ts = new TurboStream()
|
|
144
|
-
|
|
144
|
+
.custom('custom-action', 'target-id', '<p>My content</p>');
|
|
145
145
|
```
|
|
146
146
|
|
|
147
147
|
##### Using the Node.js streams API
|
|
@@ -171,7 +171,7 @@ This will render the following HTML fragment:
|
|
|
171
171
|
|
|
172
172
|
```html
|
|
173
173
|
<turbo-frame id="my-id">
|
|
174
|
-
|
|
174
|
+
<p>My content</p>
|
|
175
175
|
</turbo-stream>
|
|
176
176
|
```
|
|
177
177
|
|
|
@@ -230,47 +230,47 @@ const app = new Koa();
|
|
|
230
230
|
turbochargeKoa(app);
|
|
231
231
|
|
|
232
232
|
app.use(async (ctx, next) => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
233
|
+
if (ctx.path !== '/turbo-frame') {
|
|
234
|
+
return await next();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (ctx.isTurboFrameRequest()) {
|
|
238
|
+
// Automatically retrieves the Turbo Frame ID from the header
|
|
239
|
+
// and uses it for the response.
|
|
240
|
+
ctx.turboFrame('<p>New content</p>');
|
|
241
|
+
//You can set it manually with:
|
|
242
|
+
// ctx.turboFrame('turbo-frame-id', <p>New content</p>');
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
ctx.redirect('/path/to/other/page');
|
|
246
|
+
}
|
|
247
247
|
});
|
|
248
248
|
|
|
249
249
|
app.use(async (ctx, next) => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
250
|
+
if (ctx.path !== '/turbo-stream') {
|
|
251
|
+
return await next();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (ctx.isTurboStreamRequest()) {
|
|
255
|
+
ctx.turboStream()
|
|
256
|
+
.append('target-id', '<p>New content</p>');
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
ctx.redirect('/path/to/other/page');
|
|
260
|
+
}
|
|
261
261
|
});
|
|
262
262
|
|
|
263
263
|
app.use(async (ctx, next) => {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
if (ctx.path !== '/sse') {
|
|
265
|
+
return await next();
|
|
266
|
+
}
|
|
267
267
|
|
|
268
|
-
|
|
268
|
+
const ssets = ctx.sseTurboStream();
|
|
269
269
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
270
|
+
// These get automatically piped to ctx.res in SSE format.
|
|
271
|
+
ssets
|
|
272
|
+
.append('target-id', '<p>My content</p>')
|
|
273
|
+
.updateAll('.targets', '<p>My other content</p>');
|
|
274
274
|
});
|
|
275
275
|
|
|
276
276
|
app.listen(8080);
|
|
@@ -308,18 +308,18 @@ const app = express();
|
|
|
308
308
|
turbochargeExpress(app);
|
|
309
309
|
|
|
310
310
|
app.get('/', (req, res) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
311
|
+
if (req.isTurboFrameRequest()) {
|
|
312
|
+
res.turboFrame('<p>My content</p>');
|
|
313
|
+
}
|
|
314
|
+
else if (req.isTurboStreamRequest()) {
|
|
315
|
+
res.turboStream()
|
|
316
|
+
.append('target-id', '<p>My content</p>')
|
|
317
|
+
.remove('taget-id-2')
|
|
318
|
+
.send();
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
res.status(501).end();
|
|
322
|
+
}
|
|
323
323
|
});
|
|
324
324
|
|
|
325
325
|
app.listen(8080, () => {
|
|
@@ -338,11 +338,11 @@ import { WebSocketServer } from 'ws';
|
|
|
338
338
|
const wss = new WebSocketServer({ port: 8080 });
|
|
339
339
|
|
|
340
340
|
wss.on('connection', webSocket => {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
341
|
+
// The Turbo Stream messages get sent immediately.
|
|
342
|
+
WsTurboStream
|
|
343
|
+
.use(webSocket)
|
|
344
|
+
.append('id1', 'c1')
|
|
345
|
+
.update('id2', 'c2');
|
|
346
346
|
});
|
|
347
347
|
```
|
|
348
348
|
|
|
@@ -355,15 +355,15 @@ import { WebSocketServer, createWebSocketStream } from 'ws';
|
|
|
355
355
|
const wss = new WebSocketServer({ port: 8080 });
|
|
356
356
|
|
|
357
357
|
wss.on('connection', function connection(ws) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
358
|
+
const ts = new TurboStream();
|
|
359
|
+
const readable = ts.createReadableStream();
|
|
360
|
+
const wsStream = createWebSocketStream(ws, { encoding: 'utf8' });
|
|
361
|
+
readable.pipe(wsStream);
|
|
362
|
+
|
|
363
|
+
ts
|
|
364
|
+
.append('target-id', '<p>My content</p>')
|
|
365
|
+
.update('target-id-2', '<p>Updated content</p>')
|
|
366
|
+
.remove('target-id-2');
|
|
367
367
|
});
|
|
368
368
|
```
|
|
369
369
|
|
|
@@ -382,82 +382,82 @@ config.sseUrl = `${config.baseUrl}/sse`;
|
|
|
382
382
|
|
|
383
383
|
const httpServer = http.createServer((req, res) => {
|
|
384
384
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
385
|
+
// SSE endpoint
|
|
386
|
+
if (req.url === '/sse') {
|
|
387
|
+
|
|
388
|
+
res.writeHead(200, {
|
|
389
|
+
'Content-Type': 'text/event-stream',
|
|
390
|
+
'Cache-Control': 'no-cache',
|
|
391
|
+
...(req.httpVersionMajor === 1 && { 'Connection': 'keep-alive' })
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// Turbo listens to nameless events and 'message' events.
|
|
395
|
+
const ssets = new SseTurboStream('message');
|
|
396
|
+
|
|
397
|
+
// Timeout is only here for us to have time to observe.
|
|
398
|
+
setTimeout(() => {
|
|
399
|
+
ssets.append('stream1', '<p>My content</p>')
|
|
400
|
+
.append('stream2', '<p>My content 2</p>')
|
|
401
|
+
.append('stream3', '<p>\n<span>My multiline content 3</span>\n</p>');
|
|
402
|
+
|
|
403
|
+
res.write(ssets.flush());
|
|
404
|
+
}, 1000);
|
|
405
|
+
|
|
406
|
+
// You can also use the streams API.
|
|
407
|
+
setTimeout(() => {
|
|
408
|
+
const stream = ssets.createReadableStream();
|
|
409
|
+
stream.pipe(res);
|
|
410
|
+
ssets.prependAll('.stream', '<p>Prepend!</p>');
|
|
411
|
+
}, 2000);
|
|
412
|
+
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Client
|
|
417
|
+
res.end(`<!DOCTYPE html>
|
|
418
418
|
<html>
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
419
|
+
<head>
|
|
420
|
+
<meta charset="utf-8">
|
|
421
|
+
<title>SSE Test</title>
|
|
422
|
+
<style>
|
|
423
|
+
.b {
|
|
424
|
+
border: 1px dashed #cccc;
|
|
425
|
+
margin-bottom: 10px;
|
|
426
|
+
padding: 10px;
|
|
427
|
+
}
|
|
428
|
+
</style>
|
|
429
|
+
<script type="module" src="https://unpkg.com/@hotwired/turbo@8.0.0-beta.2/dist/turbo.es2017-esm.js"></script>
|
|
430
|
+
<script>
|
|
431
|
+
var eventSource = new EventSource('/sse');
|
|
432
|
+
eventSource.onmessage = function(event) {
|
|
433
|
+
document.getElementById('log').innerText += event.data + '\\n\\n';
|
|
434
|
+
};
|
|
435
|
+
</script>
|
|
436
|
+
</head>
|
|
437
|
+
<body>
|
|
438
|
+
<turbo-stream-source src="${ config.sseUrl }">
|
|
439
|
+
<h1>SSE Test</h1>
|
|
440
|
+
<h2>Control</h2>
|
|
441
|
+
<pre class="b" id="log"></pre>
|
|
442
|
+
<h2>stream1</h2>
|
|
443
|
+
<div class="b stream" id="stream1"></div>
|
|
444
|
+
<h2>stream2</h2>
|
|
445
|
+
<div class="b stream" id="stream2"></div>
|
|
446
|
+
<h2>stream3</h2>
|
|
447
|
+
<div class="b stream" id="stream3"></div>
|
|
448
|
+
</body>
|
|
449
449
|
</html>`);
|
|
450
450
|
});
|
|
451
451
|
|
|
452
452
|
httpServer.listen(config.port);
|
|
453
453
|
|
|
454
454
|
httpServer.on('error', (err) => {
|
|
455
|
-
|
|
456
|
-
|
|
455
|
+
console.log(err);
|
|
456
|
+
process.exit(1);
|
|
457
457
|
});
|
|
458
458
|
|
|
459
459
|
httpServer.on('listening', () => {
|
|
460
|
-
|
|
460
|
+
console.log(`HTTP server listening on port ${config.port}…`);
|
|
461
461
|
});
|
|
462
462
|
```
|
|
463
463
|
|
|
@@ -479,60 +479,60 @@ const app = new Koa();
|
|
|
479
479
|
turbochargeKoa(app);
|
|
480
480
|
|
|
481
481
|
app.use(async (ctx, next) => {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
482
|
+
if (ctx.path !== '/sse') {
|
|
483
|
+
return await next();
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Use convenience function to configure Koa.
|
|
487
|
+
// Returns SseTurboStream instance which directly streams to res.
|
|
488
|
+
const ssets = ctx.sseTurboStream();
|
|
489
|
+
|
|
490
|
+
// Timeout is only here for us to have time to observe.
|
|
491
|
+
setTimeout(() => {
|
|
492
|
+
ssets
|
|
493
|
+
.append('stream1', '<p>My content <strong>1</strong></p>')
|
|
494
|
+
.append('stream2', '<p>My content <strong>2</strong></p>')
|
|
495
|
+
.append('stream3', '<p>My content <strong>3</strong></p>');
|
|
496
|
+
}, 1000);
|
|
497
|
+
|
|
498
|
+
setTimeout(() => {
|
|
499
|
+
ssets.prependAll('.stream', '<p>Prepend all</p>');
|
|
500
|
+
}, 2000);
|
|
501
501
|
});
|
|
502
502
|
|
|
503
503
|
app.use(async (ctx, next) => {
|
|
504
|
-
|
|
504
|
+
ctx.body = `<!DOCTYPE html>
|
|
505
505
|
<html>
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
506
|
+
<head>
|
|
507
|
+
<meta charset="utf-8">
|
|
508
|
+
<title>SSE Test</title>
|
|
509
|
+
<style>
|
|
510
|
+
.b {
|
|
511
|
+
border: 1px dashed #cccc;
|
|
512
|
+
margin-bottom: 10px;
|
|
513
|
+
padding: 10px;
|
|
514
|
+
}
|
|
515
|
+
</style>
|
|
516
|
+
<script type="module" src="https://unpkg.com/@hotwired/turbo@8.0.0-beta.2/dist/turbo.es2017-esm.js"></script>
|
|
517
|
+
<script>
|
|
518
|
+
var eventSource = new EventSource('/sse');
|
|
519
|
+
eventSource.onmessage = function(event) {
|
|
520
|
+
document.getElementById('log').innerText += event.data + '\\n\\n';
|
|
521
|
+
};
|
|
522
|
+
</script>
|
|
523
|
+
</head>
|
|
524
|
+
<body>
|
|
525
|
+
<turbo-stream-source src="${ config.sseUrl }">
|
|
526
|
+
<h1>SSE Test</h1>
|
|
527
|
+
<h2>Control</h2>
|
|
528
|
+
<pre class="b" id="log"></pre>
|
|
529
|
+
<h2>stream1</h2>
|
|
530
|
+
<div class="b stream" id="stream1"></div>
|
|
531
|
+
<h2>stream2</h2>
|
|
532
|
+
<div class="b stream" id="stream2"></div>
|
|
533
|
+
<h2>stream3</h2>
|
|
534
|
+
<div class="b stream" id="stream3"></div>
|
|
535
|
+
</body>
|
|
536
536
|
</html>`;
|
|
537
537
|
});
|
|
538
538
|
|
|
@@ -559,57 +559,57 @@ turbochargeExpress(app);
|
|
|
559
559
|
// SSE endpoint
|
|
560
560
|
app.get('/sse', async (req, res) => {
|
|
561
561
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
562
|
+
// Use convenience function to configure Express.
|
|
563
|
+
// Returns SseTurboStream instance which directly streams to res.
|
|
564
|
+
const ssets = res.sseTurboStream();
|
|
565
|
+
|
|
566
|
+
// Timeout is only here for us to have time to observe.
|
|
567
|
+
setTimeout(() => {
|
|
568
|
+
ssets
|
|
569
|
+
.append('stream1', '<p>My content <strong>1</strong></p>')
|
|
570
|
+
.append('stream2', '<p>My content <strong>2</strong></p>')
|
|
571
|
+
.append('stream3', '<p>My content <strong>3</strong></p>');
|
|
572
|
+
}, 1000);
|
|
573
|
+
|
|
574
|
+
setTimeout(() => {
|
|
575
|
+
ssets.prependAll('.stream', '<p>Prepend all</p>');
|
|
576
|
+
}, 2000);
|
|
577
577
|
});
|
|
578
578
|
|
|
579
579
|
// Client
|
|
580
580
|
app.get('/', async (req, res) => {
|
|
581
|
-
|
|
581
|
+
res.send(`<!DOCTYPE html>
|
|
582
582
|
<html>
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
583
|
+
<head>
|
|
584
|
+
<meta charset="utf-8">
|
|
585
|
+
<title>SSE Test</title>
|
|
586
|
+
<style>
|
|
587
|
+
.b {
|
|
588
|
+
border: 1px dashed #cccc;
|
|
589
|
+
margin-bottom: 10px;
|
|
590
|
+
padding: 10px;
|
|
591
|
+
}
|
|
592
|
+
</style>
|
|
593
|
+
<script type="module" src="https://unpkg.com/@hotwired/turbo@8.0.0-beta.2/dist/turbo.es2017-esm.js"></script>
|
|
594
|
+
<script>
|
|
595
|
+
var eventSource = new EventSource('/sse');
|
|
596
|
+
eventSource.onmessage = function(event) {
|
|
597
|
+
document.getElementById('log').innerText += event.data + '\\n\\n';
|
|
598
|
+
};
|
|
599
|
+
</script>
|
|
600
|
+
</head>
|
|
601
|
+
<body>
|
|
602
|
+
<turbo-stream-source src="${ config.sseUrl }">
|
|
603
|
+
<h1>SSE Test</h1>
|
|
604
|
+
<h2>Control</h2>
|
|
605
|
+
<pre class="b" id="log"></pre>
|
|
606
|
+
<h2>stream1</h2>
|
|
607
|
+
<div class="b stream" id="stream1"></div>
|
|
608
|
+
<h2>stream2</h2>
|
|
609
|
+
<div class="b stream" id="stream2"></div>
|
|
610
|
+
<h2>stream3</h2>
|
|
611
|
+
<div class="b stream" id="stream3"></div>
|
|
612
|
+
</body>
|
|
613
613
|
</html>`)
|
|
614
614
|
});
|
|
615
615
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-turbo",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A library for Node.js to assist with the server side of 37signals' Hotwire Turbo framework. It provides classes and functions for Web servers and also convenience functions for the frameworks Koa and Express as well as for WebSocket and SSE.",
|
|
5
|
-
"keywords": ["turbo", "hotwire", "hotwired", "server", "http", "koa", "express", "sse", "websocket", "ws"],
|
|
5
|
+
"keywords": ["node", "turbo", "node-turbo", "nodejs", "hotwire", "hotwired", "server", "http", "koa", "express", "sse", "websocket", "ws"],
|
|
6
6
|
"homepage": "https://github.com/VividVisions/node-turbo",
|
|
7
7
|
"bugs": "https://github.com/VividVisions/node-turbo/issues",
|
|
8
8
|
"repository": {
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"is-plain-object": "^5.0.0",
|
|
48
|
-
"negotiator": "^0.6.3"
|
|
48
|
+
"negotiator": "^0.6.3",
|
|
49
|
+
"debug": "^4.3.4"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@enterthenamehere/esdoc": "^2.6.0-dev.1",
|
|
@@ -59,7 +60,6 @@
|
|
|
59
60
|
"chai-eventemitter2": "^0.2.1",
|
|
60
61
|
"chai-spies": "^1.1.0",
|
|
61
62
|
"colorette": "^2.0.20",
|
|
62
|
-
"debug": "^4.3.4",
|
|
63
63
|
"eventsource": "^2.0.2",
|
|
64
64
|
"express": "^4.18.2",
|
|
65
65
|
"git-repo-info": "^2.1.1",
|