create-rudder-app 1.1.2 → 1.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.
Files changed (113) hide show
  1. package/dist/cli-flags.d.ts +0 -9
  2. package/dist/cli-flags.d.ts.map +1 -1
  3. package/dist/cli-flags.js +0 -8
  4. package/dist/cli-flags.js.map +1 -1
  5. package/dist/index.js +2 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/templates/app/service-provider.d.ts.map +1 -1
  8. package/dist/templates/app/service-provider.js +0 -15
  9. package/dist/templates/app/service-provider.js.map +1 -1
  10. package/dist/templates/components/site-header.d.ts.map +1 -1
  11. package/dist/templates/components/site-header.js +2 -8
  12. package/dist/templates/components/site-header.js.map +1 -1
  13. package/dist/templates/package-json.d.ts.map +1 -1
  14. package/dist/templates/package-json.js +4 -5
  15. package/dist/templates/package-json.js.map +1 -1
  16. package/dist/templates/pages/index.d.ts +13 -0
  17. package/dist/templates/pages/index.d.ts.map +1 -1
  18. package/dist/templates/pages/index.js +43 -0
  19. package/dist/templates/pages/index.js.map +1 -1
  20. package/dist/templates/routes/api.d.ts.map +1 -1
  21. package/dist/templates/routes/api.js +0 -99
  22. package/dist/templates/routes/api.js.map +1 -1
  23. package/dist/templates/routes/console.d.ts.map +1 -1
  24. package/dist/templates/routes/console.js +3 -4
  25. package/dist/templates/routes/console.js.map +1 -1
  26. package/dist/templates/routes/web.d.ts.map +1 -1
  27. package/dist/templates/routes/web.js +10 -83
  28. package/dist/templates/routes/web.js.map +1 -1
  29. package/dist/templates/routes-manifest.d.ts +2 -2
  30. package/dist/templates/routes-manifest.d.ts.map +1 -1
  31. package/dist/templates/routes-manifest.js +19 -22
  32. package/dist/templates/routes-manifest.js.map +1 -1
  33. package/dist/templates/views/welcome.d.ts +13 -0
  34. package/dist/templates/views/welcome.d.ts.map +1 -1
  35. package/dist/templates/views/welcome.js +53 -0
  36. package/dist/templates/views/welcome.js.map +1 -1
  37. package/dist/templates.d.ts +0 -9
  38. package/dist/templates.d.ts.map +1 -1
  39. package/dist/templates.js +38 -120
  40. package/dist/templates.js.map +1 -1
  41. package/package.json +1 -5
  42. package/dist/templates/demos/avatar.d.ts +0 -3
  43. package/dist/templates/demos/avatar.d.ts.map +0 -1
  44. package/dist/templates/demos/avatar.js +0 -174
  45. package/dist/templates/demos/avatar.js.map +0 -1
  46. package/dist/templates/demos/cache.d.ts +0 -3
  47. package/dist/templates/demos/cache.d.ts.map +0 -1
  48. package/dist/templates/demos/cache.js +0 -91
  49. package/dist/templates/demos/cache.js.map +0 -1
  50. package/dist/templates/demos/contact.d.ts +0 -3
  51. package/dist/templates/demos/contact.d.ts.map +0 -1
  52. package/dist/templates/demos/contact.js +0 -99
  53. package/dist/templates/demos/contact.js.map +0 -1
  54. package/dist/templates/demos/fibonacci.d.ts +0 -7
  55. package/dist/templates/demos/fibonacci.d.ts.map +0 -1
  56. package/dist/templates/demos/fibonacci.js +0 -164
  57. package/dist/templates/demos/fibonacci.js.map +0 -1
  58. package/dist/templates/demos/http.d.ts +0 -3
  59. package/dist/templates/demos/http.d.ts.map +0 -1
  60. package/dist/templates/demos/http.js +0 -109
  61. package/dist/templates/demos/http.js.map +0 -1
  62. package/dist/templates/demos/index-view.d.ts +0 -3
  63. package/dist/templates/demos/index-view.d.ts.map +0 -1
  64. package/dist/templates/demos/index-view.js +0 -47
  65. package/dist/templates/demos/index-view.js.map +0 -1
  66. package/dist/templates/demos/localization.d.ts +0 -4
  67. package/dist/templates/demos/localization.d.ts.map +0 -1
  68. package/dist/templates/demos/localization.js +0 -122
  69. package/dist/templates/demos/localization.js.map +0 -1
  70. package/dist/templates/demos/mail.d.ts +0 -4
  71. package/dist/templates/demos/mail.d.ts.map +0 -1
  72. package/dist/templates/demos/mail.js +0 -119
  73. package/dist/templates/demos/mail.js.map +0 -1
  74. package/dist/templates/demos/notifications.d.ts +0 -4
  75. package/dist/templates/demos/notifications.d.ts.map +0 -1
  76. package/dist/templates/demos/notifications.js +0 -125
  77. package/dist/templates/demos/notifications.js.map +0 -1
  78. package/dist/templates/demos/pennant.d.ts +0 -8
  79. package/dist/templates/demos/pennant.d.ts.map +0 -1
  80. package/dist/templates/demos/pennant.js +0 -135
  81. package/dist/templates/demos/pennant.js.map +0 -1
  82. package/dist/templates/demos/polymorphic.d.ts +0 -19
  83. package/dist/templates/demos/polymorphic.d.ts.map +0 -1
  84. package/dist/templates/demos/polymorphic.js +0 -663
  85. package/dist/templates/demos/polymorphic.js.map +0 -1
  86. package/dist/templates/demos/queue.d.ts +0 -4
  87. package/dist/templates/demos/queue.d.ts.map +0 -1
  88. package/dist/templates/demos/queue.js +0 -99
  89. package/dist/templates/demos/queue.js.map +0 -1
  90. package/dist/templates/demos/registry.d.ts +0 -26
  91. package/dist/templates/demos/registry.d.ts.map +0 -1
  92. package/dist/templates/demos/registry.js +0 -140
  93. package/dist/templates/demos/registry.js.map +0 -1
  94. package/dist/templates/demos/rudder-socket.d.ts +0 -2
  95. package/dist/templates/demos/rudder-socket.d.ts.map +0 -1
  96. package/dist/templates/demos/rudder-socket.js +0 -95
  97. package/dist/templates/demos/rudder-socket.js.map +0 -1
  98. package/dist/templates/demos/sync.d.ts +0 -2
  99. package/dist/templates/demos/sync.d.ts.map +0 -1
  100. package/dist/templates/demos/sync.js +0 -90
  101. package/dist/templates/demos/sync.js.map +0 -1
  102. package/dist/templates/demos/system-info.d.ts +0 -3
  103. package/dist/templates/demos/system-info.d.ts.map +0 -1
  104. package/dist/templates/demos/system-info.js +0 -134
  105. package/dist/templates/demos/system-info.js.map +0 -1
  106. package/dist/templates/demos/todos.d.ts +0 -6
  107. package/dist/templates/demos/todos.d.ts.map +0 -1
  108. package/dist/templates/demos/todos.js +0 -238
  109. package/dist/templates/demos/todos.js.map +0 -1
  110. package/dist/templates/demos/ws.d.ts +0 -2
  111. package/dist/templates/demos/ws.d.ts.map +0 -1
  112. package/dist/templates/demos/ws.js +0 -99
  113. package/dist/templates/demos/ws.js.map +0 -1
@@ -1,99 +0,0 @@
1
- // Queue dispatch demo — Job class in app/Jobs/ + dispatch endpoint that
2
- // enqueues it. Default driver is in-memory; the worker drains during dev.
3
- export function demosQueueView() {
4
- return `import { useState } from 'react'
5
- import '@/index.css'
6
- import { SiteHeader } from 'App/Components/SiteHeader.js'
7
-
8
- interface QueueResponse {
9
- ok: boolean
10
- queue: string
11
- dispatchedAt: string
12
- }
13
-
14
- export default function QueueDemo() {
15
- const [results, setResults] = useState<QueueResponse[]>([])
16
- const [loading, setLoading] = useState(false)
17
-
18
- async function dispatch() {
19
- setLoading(true)
20
- try {
21
- const res = await fetch('/api/queue/dispatch', { method: 'POST' })
22
- const data = await res.json() as QueueResponse
23
- setResults(prev => [data, ...prev].slice(0, 10))
24
- } finally {
25
- setLoading(false)
26
- }
27
- }
28
-
29
- return (
30
- <div className="page">
31
- <SiteHeader />
32
-
33
- <section className="hero">
34
- <h1 className="hero-title">Queue dispatch</h1>
35
- <p className="hero-lead">
36
- Click to dispatch <code className="inline-code">ExampleJob</code> via{' '}
37
- <code className="inline-code">@rudderjs/queue</code>. The handler logs to the
38
- server terminal — install <code className="inline-code">@rudderjs/horizon</code> to see
39
- dispatched jobs in a UI.
40
- </p>
41
- </section>
42
-
43
- <section className="feature-section" style={{ maxWidth: '32rem', margin: '0 auto' }}>
44
- <div className="form-card">
45
- <button className="form-submit" onClick={dispatch} disabled={loading} style={{ marginBottom: '1rem' }}>
46
- {loading ? 'Dispatching…' : 'Dispatch ExampleJob'}
47
- </button>
48
- {results.length === 0 && (
49
- <p className="feature-desc" style={{ fontSize: '0.75rem', textAlign: 'center' }}>
50
- No dispatches yet.
51
- </p>
52
- )}
53
- {results.map((r, i) => (
54
- <p key={i} className="feature-desc" style={{ fontSize: '0.75rem', fontFamily: 'monospace', marginBottom: '0.25rem' }}>
55
- · {r.dispatchedAt} · queue={r.queue}
56
- </p>
57
- ))}
58
- </div>
59
- </section>
60
- </div>
61
- )
62
- }
63
- `;
64
- }
65
- export function exampleJob() {
66
- return `import { Job } from '@rudderjs/queue'
67
-
68
- /**
69
- * Example job for the queue demo. Logs to the server terminal when run
70
- * by the worker. Replace with whatever async work the queue should handle
71
- * (sending mail, generating reports, syncing third-party data, …).
72
- */
73
- export class ExampleJob extends Job {
74
- static override queue = 'default'
75
- static override retries = 3
76
-
77
- constructor(private readonly payload: string = 'hello') {
78
- super()
79
- }
80
-
81
- async handle(): Promise<void> {
82
- console.log(\`[ExampleJob] handling: \${this.payload}\`)
83
- }
84
-
85
- failed(error: unknown): void {
86
- console.error('[ExampleJob] failed after all retries:', error)
87
- }
88
- }
89
- `;
90
- }
91
- export function demosQueueApiBlock() {
92
- return `// POST /api/queue/dispatch — enqueue ExampleJob. Worker drains it during dev.
93
- router.post('/api/queue/dispatch', async (_req, res) => {
94
- const { ExampleJob } = await import('../app/Jobs/ExampleJob.ts')
95
- await ExampleJob.dispatch('hello from /api/queue/dispatch').send()
96
- res.json({ ok: true, queue: 'default', dispatchedAt: new Date().toISOString() })
97
- })`;
98
- }
99
- //# sourceMappingURL=queue.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../src/templates/demos/queue.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,0EAA0E;AAE1E,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuBR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;;GAKN,CAAA;AACH,CAAC"}
@@ -1,26 +0,0 @@
1
- import type { TemplateContext } from '../../templates.js';
2
- export interface DemoSpec {
3
- /** Stable id used in URLs, file names, and the prompt multiselect. */
4
- value: string;
5
- /** Short label shown in the @clack/prompts multiselect. */
6
- label: string;
7
- /** Single-line hint shown next to the label in the prompt. */
8
- hint?: string;
9
- /** Card title shown on /demos. Falls back to `label` when omitted. */
10
- title?: string;
11
- /** Long description shown on the /demos card in the scaffolded app + playground. */
12
- description: string;
13
- /** Packages this demo exercises — rendered under each /demos card. */
14
- packages: ReadonlyArray<string>;
15
- /** Package keys that must all be selected for this demo to scaffold. */
16
- requires?: ReadonlyArray<keyof TemplateContext['packages']>;
17
- /** True if this demo requires a database/ORM. */
18
- requiresOrm?: boolean;
19
- }
20
- /** Card title used on /demos — falls back to `label` when not overridden. */
21
- export declare function demoTitle(spec: DemoSpec): string;
22
- export declare const DEMOS: ReadonlyArray<DemoSpec>;
23
- export declare function availableDemos(orm: TemplateContext['orm'], packages: TemplateContext['packages']): DemoSpec[];
24
- /** Default href for a demo card — `/demos/<value>`. */
25
- export declare function demoHref(spec: Pick<DemoSpec, 'value'>): string;
26
- //# sourceMappingURL=registry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,KAAK,EAAS,MAAM,CAAA;IACpB,2DAA2D;IAC3D,KAAK,EAAS,MAAM,CAAA;IACpB,8DAA8D;IAC9D,IAAI,CAAC,EAAS,MAAM,CAAA;IACpB,sEAAsE;IACtE,KAAK,CAAC,EAAQ,MAAM,CAAA;IACpB,oFAAoF;IACpF,WAAW,EAAG,MAAM,CAAA;IACpB,sEAAsE;IACtE,QAAQ,EAAM,aAAa,CAAC,MAAM,CAAC,CAAA;IACnC,wEAAwE;IACxE,QAAQ,CAAC,EAAK,aAAa,CAAC,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC,CAAA;IAC9D,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEhD;AAED,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC,QAAQ,CAyHzC,CAAA;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,GACpC,QAAQ,EAAE,CAMZ;AAED,uDAAuD;AACvD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,MAAM,CAE9D"}
@@ -1,140 +0,0 @@
1
- /** Card title used on /demos — falls back to `label` when not overridden. */
2
- export function demoTitle(spec) {
3
- return spec.title ?? spec.label;
4
- }
5
- export const DEMOS = [
6
- {
7
- value: 'contact',
8
- label: 'Contact form',
9
- hint: 'CSRF + Zod validation',
10
- description: 'CSRF-protected form with Zod validation. Demonstrates getCsrfToken() and FormRequest-style error handling.',
11
- packages: ['@rudderjs/middleware', '@rudderjs/core'],
12
- },
13
- {
14
- value: 'cache',
15
- label: 'Cache counter',
16
- hint: 'Cache.get + Cache.set round-trip',
17
- description: 'Click "Bump" to read the current value via Cache.get, increment it, and write it back via Cache.set. Default driver is in-memory.',
18
- packages: ['@rudderjs/cache'],
19
- },
20
- {
21
- value: 'todos',
22
- label: 'Todos CRUD',
23
- title: 'Todos',
24
- hint: 'requires ORM',
25
- description: 'ORM + interactive UI. Controller loads initial data, the view hydrates and POSTs to /api/todos/* for live updates.',
26
- packages: ['@rudderjs/orm', '@rudderjs/router'],
27
- requiresOrm: true,
28
- },
29
- {
30
- value: 'polymorphic',
31
- label: 'Polymorphic relations',
32
- hint: 'requires ORM',
33
- description: 'morphMany + morphTo + morphToMany / morphedByMany via @rudderjs/orm. One Comment table belongs to either a Post or a Video; Posts and Videos share a Tag table through a single polymorphic pivot. End-to-end demo of every polymorphic relation type.',
34
- packages: ['@rudderjs/orm'],
35
- requiresOrm: true,
36
- },
37
- {
38
- value: 'queue',
39
- label: 'Queue dispatch',
40
- hint: 'requires Queue',
41
- description: 'Dispatch ExampleJob via @rudderjs/queue. The handler logs to the server terminal — install @rudderjs/horizon for a UI.',
42
- packages: ['@rudderjs/queue'],
43
- requires: ['queue'],
44
- },
45
- {
46
- value: 'mail',
47
- label: 'Mail send',
48
- hint: 'requires Mail',
49
- description: 'Send a DemoMail via @rudderjs/mail. Default driver is log — output lands in the dev server terminal.',
50
- packages: ['@rudderjs/mail'],
51
- requires: ['mail'],
52
- },
53
- {
54
- value: 'notifications',
55
- label: 'Notifications',
56
- hint: 'requires Notifications + Mail',
57
- description: "Dispatch a WelcomeNotification via notify(). The notification's via() picks the channel(s); mail routes through the log driver.",
58
- packages: ['@rudderjs/notification', '@rudderjs/mail'],
59
- requires: ['notifications', 'mail'],
60
- },
61
- {
62
- value: 'localization',
63
- label: 'Localization',
64
- hint: 'requires Localization',
65
- description: 'Locale switcher resolves the same keys server-side via trans(). Strings live in lang/<locale>/messages.json.',
66
- packages: ['@rudderjs/localization'],
67
- requires: ['localization'],
68
- },
69
- {
70
- value: 'http',
71
- label: 'HTTP client',
72
- hint: 'requires HTTP',
73
- description: 'Server-side Http.retry(3, 200).timeout(5000).get(url) against a public API. The 500 endpoint exercises the retry path.',
74
- packages: ['@rudderjs/http'],
75
- requires: ['http'],
76
- },
77
- {
78
- value: 'avatar',
79
- label: 'Avatar resize',
80
- hint: 'requires Storage + Image',
81
- description: 'Upload an image — server resizes it to 256×256 WebP via @rudderjs/image and saves to public storage. Side-by-side compare.',
82
- packages: ['@rudderjs/image', '@rudderjs/storage'],
83
- requires: ['storage', 'image'],
84
- },
85
- {
86
- value: 'fibonacci',
87
- label: 'Worker threads',
88
- hint: 'requires Concurrency',
89
- description: 'Compute fib(n) sequentially on the main thread vs across @rudderjs/concurrency worker pool. Watch the parallel cost stay flat as you crank N.',
90
- packages: ['@rudderjs/concurrency'],
91
- requires: ['concurrency'],
92
- },
93
- {
94
- value: 'system-info',
95
- label: 'System info',
96
- hint: 'requires Process',
97
- description: 'Three shell commands (git, node, uptime) executed via @rudderjs/process. Compares sequential vs parallel cost using Process.pool().',
98
- packages: ['@rudderjs/process'],
99
- requires: ['process'],
100
- },
101
- {
102
- value: 'pennant',
103
- label: 'Feature flags',
104
- hint: 'requires Pennant + Auth',
105
- description: 'Boolean, value, scoped, and Lottery features resolved against the current user. Sub-route guarded by FeatureMiddleware to demonstrate 403 blocking.',
106
- packages: ['@rudderjs/pennant'],
107
- requires: ['pennant', 'auth'],
108
- },
109
- {
110
- value: 'ws',
111
- label: 'WebSocket chat',
112
- hint: 'requires WebSocket / Broadcast',
113
- description: 'Real-time chat + presence using @rudderjs/broadcast — multi-channel pub/sub over a single WebSocket connection.',
114
- packages: ['@rudderjs/broadcast'],
115
- requires: ['broadcast'],
116
- },
117
- {
118
- value: 'sync',
119
- label: 'Yjs collaboration',
120
- title: 'Collaborative editor',
121
- hint: 'requires Sync',
122
- description: 'Yjs CRDT live document with awareness cursors. Open in two tabs to see real-time sync over @rudderjs/sync.',
123
- packages: ['@rudderjs/sync'],
124
- requires: ['sync'],
125
- },
126
- ];
127
- export function availableDemos(orm, packages) {
128
- return DEMOS.filter(d => {
129
- if (d.requiresOrm && orm === false)
130
- return false;
131
- if (d.requires)
132
- return d.requires.every(p => packages[p]);
133
- return true;
134
- });
135
- }
136
- /** Default href for a demo card — `/demos/<value>`. */
137
- export function demoHref(spec) {
138
- return `/demos/${spec.value}`;
139
- }
140
- //# sourceMappingURL=registry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/templates/demos/registry.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export declare function rudderSocketSource(): string;
2
- //# sourceMappingURL=rudder-socket.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rudder-socket.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/rudder-socket.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,IAAI,MAAM,CA6F3C"}
@@ -1,95 +0,0 @@
1
- export function rudderSocketSource() {
2
- return `// RudderSocket — RudderJS WebSocket client
3
- //
4
- // Multiplexes channels and presence rooms over a single WebSocket connection.
5
- // Mirrors the API expected by @rudderjs/broadcast on the server.
6
-
7
- type Listener = (data: unknown) => void
8
-
9
- class Channel {
10
- private listeners = new Map<string, Set<Listener>>()
11
-
12
- constructor(
13
- private readonly socket: RudderSocket,
14
- public readonly name: string,
15
- ) {}
16
-
17
- on(event: string, fn: Listener): this {
18
- if (!this.listeners.has(event)) this.listeners.set(event, new Set())
19
- this.listeners.get(event)!.add(fn)
20
- return this
21
- }
22
-
23
- off(event: string, fn: Listener): this {
24
- this.listeners.get(event)?.delete(fn)
25
- return this
26
- }
27
-
28
- /** @internal — invoked by RudderSocket on incoming messages */
29
- receive(event: string, data: unknown) {
30
- this.listeners.get(event)?.forEach(fn => fn(data))
31
- }
32
-
33
- /** @internal — invoked by RudderSocket to (re)subscribe after connect */
34
- subscribe() {
35
- this.socket.send({ type: 'subscribe', channel: this.name })
36
- }
37
- }
38
-
39
- class Presence extends Channel {
40
- constructor(socket: RudderSocket, name: string, private readonly token: string) {
41
- super(socket, name)
42
- }
43
-
44
- override subscribe() {
45
- this.socket.send({ type: 'presence.join', channel: this.name, token: this.token })
46
- }
47
- }
48
-
49
- export class RudderSocket {
50
- private ws?: WebSocket
51
- private readonly channels = new Map<string, Channel>()
52
- private reconnectTimer?: ReturnType<typeof setTimeout>
53
-
54
- constructor(private readonly url: string) {
55
- this.connect()
56
- }
57
-
58
- channel(name: string): Channel {
59
- let ch = this.channels.get(name)
60
- if (!ch) { ch = new Channel(this, name); this.channels.set(name, ch); ch.subscribe() }
61
- return ch
62
- }
63
-
64
- presence(name: string, token: string): Channel {
65
- let ch = this.channels.get(name)
66
- if (!ch) { ch = new Presence(this, name, token); this.channels.set(name, ch); ch.subscribe() }
67
- return ch
68
- }
69
-
70
- send(payload: Record<string, unknown>) {
71
- if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(payload))
72
- }
73
-
74
- close() {
75
- if (this.reconnectTimer) clearTimeout(this.reconnectTimer)
76
- this.ws?.close()
77
- }
78
-
79
- private connect() {
80
- this.ws = new WebSocket(this.url)
81
- this.ws.onopen = () => this.channels.forEach(ch => ch.subscribe())
82
- this.ws.onmessage = (e) => {
83
- try {
84
- const msg = JSON.parse(e.data as string) as { channel?: string; event?: string; data?: unknown }
85
- if (msg.channel && msg.event) this.channels.get(msg.channel)?.receive(msg.event, msg.data)
86
- } catch { /* ignore non-JSON frames */ }
87
- }
88
- this.ws.onclose = () => {
89
- this.reconnectTimer = setTimeout(() => this.connect(), 1500)
90
- }
91
- }
92
- }
93
- `;
94
- }
95
- //# sourceMappingURL=rudder-socket.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rudder-socket.js","sourceRoot":"","sources":["../../../src/templates/demos/rudder-socket.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2FR,CAAA;AACD,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare function demosSyncView(): string;
2
- //# sourceMappingURL=sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/sync.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,IAAI,MAAM,CAwFtC"}
@@ -1,90 +0,0 @@
1
- export function demosSyncView() {
2
- return `import '@/index.css'
3
- import { SiteHeader } from 'App/Components/SiteHeader.js'
4
- import { useEffect, useRef, useState } from 'react'
5
- import * as Y from 'yjs'
6
- import { WebsocketProvider } from 'y-websocket'
7
-
8
- function getWsUrl() {
9
- if (typeof window === 'undefined') return ''
10
- return \`ws://\${window.location.host}/ws-sync\`
11
- }
12
-
13
- export default function SyncDemo() {
14
- const [connected, setConnected] = useState(false)
15
- const [text, setText] = useState('')
16
- const [users, setUsers] = useState<{ name: string; color: string }[]>([])
17
- const [myName] = useState(() => \`User-\${Math.floor(Math.random() * 1000)}\`)
18
- const [myColor] = useState(() => \`hsl(\${Math.floor(Math.random() * 360)}, 70%, 50%)\`)
19
-
20
- const docRef = useRef<Y.Doc | null>(null)
21
- const provRef = useRef<WebsocketProvider | null>(null)
22
- const textareaRef = useRef<HTMLTextAreaElement>(null)
23
-
24
- useEffect(() => {
25
- const doc = new Y.Doc()
26
- const ytext = doc.getText('content')
27
- const provider = new WebsocketProvider(getWsUrl(), 'sync-demo', doc)
28
-
29
- docRef.current = doc
30
- provRef.current = provider
31
-
32
- ytext.observe(() => setText(ytext.toString()))
33
- provider.on('status', ({ status }: { status: string }) => setConnected(status === 'connected'))
34
- provider.awareness.setLocalStateField('user', { name: myName, color: myColor })
35
-
36
- const syncUsers = () => {
37
- const states = [...provider.awareness.getStates().values()] as { user?: { name: string; color: string } }[]
38
- setUsers(states.map(s => s.user).filter((u): u is { name: string; color: string } => Boolean(u)))
39
- }
40
- provider.awareness.on('change', syncUsers)
41
- syncUsers()
42
-
43
- return () => { provider.destroy(); doc.destroy() }
44
- }, [myName, myColor])
45
-
46
- function onChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
47
- const ytext = docRef.current?.getText('content')
48
- if (!ytext) return
49
- docRef.current?.transact(() => {
50
- ytext.delete(0, ytext.length)
51
- ytext.insert(0, e.target.value)
52
- })
53
- }
54
-
55
- return (
56
- <div className="page">
57
- <SiteHeader />
58
-
59
- <section className="hero">
60
- <h1 className="hero-title">Collaborative editor</h1>
61
- <p className="hero-lead">
62
- Yjs CRDT over @rudderjs/sync. Open this page in two tabs to see real-time updates.{' '}
63
- {connected ? '🟢 connected' : '⚪ connecting…'}
64
- </p>
65
- </section>
66
-
67
- <section className="feature-section" style={{ maxWidth: '40rem', margin: '0 auto' }}>
68
- <p className="form-label">Active users:</p>
69
- <ul style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', marginBottom: '1rem' }}>
70
- {users.map((u, i) => (
71
- <li key={i} className="inline-code" style={{ borderLeft: \`3px solid \${u.color}\`, paddingLeft: '0.5rem' }}>
72
- {u.name}
73
- </li>
74
- ))}
75
- </ul>
76
- <textarea
77
- ref={textareaRef}
78
- className="form-input"
79
- rows={10}
80
- value={text}
81
- onChange={onChange}
82
- placeholder="Start typing…"
83
- />
84
- </section>
85
- </div>
86
- )
87
- }
88
- `;
89
- }
90
- //# sourceMappingURL=sync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/templates/demos/sync.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsFR,CAAA;AACD,CAAC"}
@@ -1,3 +0,0 @@
1
- export declare function demosSystemInfoView(): string;
2
- export declare function demosSystemInfoApiBlock(): string;
3
- //# sourceMappingURL=system-info.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"system-info.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/system-info.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,IAAI,MAAM,CAoG5C;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CA6BhD"}
@@ -1,134 +0,0 @@
1
- // SystemInfo demo — three shell commands run via @rudderjs/process,
2
- // comparing sequential vs parallel cost via Process.pool().
3
- export function demosSystemInfoView() {
4
- return `import { useState } from 'react'
5
- import '@/index.css'
6
- import { SiteHeader } from 'App/Components/SiteHeader.js'
7
-
8
- interface CommandResult {
9
- command: string
10
- ok: boolean
11
- exitCode: number
12
- duration: number
13
- stdout: string
14
- stderr: string
15
- }
16
-
17
- interface SystemInfoResponse {
18
- results: CommandResult[]
19
- totalMs: number
20
- parallelMs: number
21
- }
22
-
23
- export default function SystemInfo() {
24
- const [data, setData ] = useState<SystemInfoResponse | null>(null)
25
- const [loading, setLoading] = useState(false)
26
- const [error, setError ] = useState<string | null>(null)
27
-
28
- async function run() {
29
- setLoading(true); setError(null)
30
- try {
31
- const res = await fetch('/api/system-info')
32
- const body = await res.json() as SystemInfoResponse | { message: string }
33
- if (!res.ok) throw new Error((body as { message: string }).message ?? 'Failed')
34
- setData(body as SystemInfoResponse)
35
- } catch (e) {
36
- setError((e as Error).message)
37
- } finally {
38
- setLoading(false)
39
- }
40
- }
41
-
42
- return (
43
- <div className="page">
44
- <SiteHeader />
45
-
46
- <section className="hero">
47
- <h1 className="hero-title">System Info</h1>
48
- <p className="hero-lead">
49
- Three shell commands run in parallel via{' '}
50
- <code className="inline-code">@rudderjs/process</code> —{' '}
51
- <code className="inline-code">git rev-parse HEAD</code>,{' '}
52
- <code className="inline-code">node --version</code>,{' '}
53
- <code className="inline-code">uptime</code>. Click run to dispatch.
54
- </p>
55
- </section>
56
-
57
- <section className="feature-section">
58
- <div className="form-card">
59
- <button
60
- className="form-submit"
61
- onClick={run}
62
- disabled={loading}
63
- style={{ marginBottom: '1rem' }}
64
- >
65
- {loading ? 'Running…' : 'Run commands'}
66
- </button>
67
-
68
- {error && <p className="form-error">{error}</p>}
69
-
70
- {data && (
71
- <>
72
- <p className="feature-desc" style={{ fontSize: '0.75rem', marginBottom: '0.75rem' }}>
73
- 3 commands · sequential cost {data.totalMs}ms · parallel cost {data.parallelMs}ms
74
- {' · '}
75
- <strong>{Math.round((1 - data.parallelMs / data.totalMs) * 100)}% faster</strong> via{' '}
76
- <code className="inline-code">Process.pool()</code>
77
- </p>
78
-
79
- {data.results.map((r, i) => (
80
- <div key={i} style={{ marginBottom: '0.75rem', padding: '0.75rem', borderRadius: '0.375rem', border: '1px solid var(--border, #e5e7eb)' }}>
81
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.25rem' }}>
82
- <code style={{ fontSize: '0.85rem', fontWeight: 600 }}>{r.command}</code>
83
- <span style={{ fontSize: '0.7rem', opacity: 0.7 }}>
84
- exit {r.exitCode} · {r.duration}ms
85
- </span>
86
- </div>
87
- {r.stdout && (
88
- <pre style={{ margin: 0, padding: '0.5rem', borderRadius: '0.25rem', background: 'var(--muted, #f4f4f5)', fontSize: '0.75rem', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>{r.stdout}</pre>
89
- )}
90
- {r.stderr && (
91
- <pre style={{ margin: '0.25rem 0 0', padding: '0.5rem', borderRadius: '0.25rem', background: 'var(--destructive-bg, #fef2f2)', color: 'var(--destructive, #b91c1c)', fontSize: '0.75rem', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>{r.stderr}</pre>
92
- )}
93
- </div>
94
- ))}
95
- </>
96
- )}
97
- </div>
98
- </section>
99
- </div>
100
- )
101
- }
102
- `;
103
- }
104
- export function demosSystemInfoApiBlock() {
105
- return `// GET /api/system-info — three shell commands, sequential vs Process.pool() parallel.
106
- router.get('/api/system-info', async (_req, res) => {
107
- const { Process } = await import('@rudderjs/process')
108
- const commands = ['git rev-parse HEAD', 'node --version', 'uptime']
109
-
110
- const sequential: { command: string; duration: number }[] = []
111
- for (const cmd of commands) {
112
- const t0 = Date.now()
113
- await Process.run(cmd)
114
- sequential.push({ command: cmd, duration: Date.now() - t0 })
115
- }
116
- const totalMs = sequential.reduce((sum, r) => sum + r.duration, 0)
117
-
118
- const t0 = Date.now()
119
- const pool = await Process.pool(commands)
120
- const parallelMs = Date.now() - t0
121
-
122
- const results = pool.results.map((r, i) => ({
123
- command: commands[i],
124
- ok: r.successful(),
125
- exitCode: r.exitCode,
126
- duration: sequential[i]!.duration,
127
- stdout: r.stdout.trim(),
128
- stderr: r.stderr.trim(),
129
- }))
130
-
131
- res.json({ results, totalMs, parallelMs })
132
- })`;
133
- }
134
- //# sourceMappingURL=system-info.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"system-info.js","sourceRoot":"","sources":["../../../src/templates/demos/system-info.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,4DAA4D;AAE5D,MAAM,UAAU,mBAAmB;IACjC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkGR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BN,CAAA;AACH,CAAC"}
@@ -1,6 +0,0 @@
1
- export declare function demosTodosView(): string;
2
- export declare function todoModelPrisma(): string;
3
- export declare function todoSchema(): string;
4
- export declare function todoService(): string;
5
- export declare function todoServiceProvider(): string;
6
- //# sourceMappingURL=todos.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"todos.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/todos.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,IAAI,MAAM,CAoHvC;AAED,wBAAgB,eAAe,IAAI,MAAM,CASxC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAwBnC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAgCpC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CA8C5C"}