@quilted/create 0.2.47 → 0.2.48

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 (23) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/esm/node_modules/.pnpm/@nodelib_fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/index.mjs +1 -1
  3. package/build/esm/node_modules/.pnpm/@nodelib_fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/async.mjs +1 -1
  4. package/build/esm/node_modules/.pnpm/@nodelib_fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/sync.mjs +1 -1
  5. package/build/esm/node_modules/.pnpm/@nodelib_fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.mjs +1 -1
  6. package/build/esm/node_modules/.pnpm/@nodelib_fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/index.mjs +1 -1
  7. package/build/esm/node_modules/.pnpm/@nodelib_fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/async.mjs +1 -1
  8. package/build/esm/node_modules/.pnpm/@nodelib_fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/sync.mjs +1 -1
  9. package/build/esm/node_modules/.pnpm/@nodelib_fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/settings.mjs +1 -1
  10. package/build/esm/node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/dist/prompts.mjs +1 -1
  11. package/build/esm/node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/lib/prompts.mjs +1 -1
  12. package/build/esnext/_virtual/index7.esnext +2 -2
  13. package/build/esnext/_virtual/index8.esnext +2 -2
  14. package/build/esnext/node_modules/.pnpm/dir-glob@3.0.1/node_modules/dir-glob/index.esnext +1 -1
  15. package/build/esnext/node_modules/.pnpm/fast-glob@3.3.3/node_modules/fast-glob/out/utils/index.esnext +1 -1
  16. package/package.json +1 -1
  17. package/templates/app-basic/browser.tsx +41 -10
  18. package/templates/app-basic/server.tsx +9 -3
  19. package/templates/app-graphql/browser.tsx +52 -20
  20. package/templates/app-graphql/server.tsx +23 -13
  21. package/templates/app-graphql/shared/context.ts +9 -1
  22. package/templates/app-trpc/browser.tsx +49 -20
  23. package/templates/app-trpc/server.tsx +16 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @quilted/create
2
2
 
3
+ ## 0.2.48
4
+
5
+ ### Patch Changes
6
+
7
+ - [`1abfd9e`](https://github.com/lemonmade/quilt/commit/1abfd9e7f163065bec12db6220fda7a800641b7b) Thanks [@lemonmade](https://github.com/lemonmade)! - Use classes for complex template browser and server entrypoints
8
+
3
9
  ## 0.2.47
4
10
 
5
11
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { __exports as out } from '../../../../../../../_virtual/index10.mjs';
1
+ import { __exports as out } from '../../../../../../../_virtual/index11.mjs';
2
2
  import { __require as requireAsync } from './providers/async.mjs';
3
3
  import { __require as requireSync } from './providers/sync.mjs';
4
4
  import { __require as requireSettings } from './settings.mjs';
@@ -1,4 +1,4 @@
1
- import { __exports as async } from '../../../../../../../../_virtual/async3.mjs';
1
+ import { __exports as async } from '../../../../../../../../_virtual/async4.mjs';
2
2
 
3
3
  var hasRequiredAsync;
4
4
  function requireAsync() {
@@ -1,4 +1,4 @@
1
- import { __exports as sync } from '../../../../../../../../_virtual/sync3.mjs';
1
+ import { __exports as sync } from '../../../../../../../../_virtual/sync4.mjs';
2
2
 
3
3
  var hasRequiredSync;
4
4
  function requireSync() {
@@ -1,4 +1,4 @@
1
- import { __exports as settings } from '../../../../../../../_virtual/settings2.mjs';
1
+ import { __exports as settings } from '../../../../../../../_virtual/settings3.mjs';
2
2
  import { __require as requireFs } from './adapters/fs.mjs';
3
3
 
4
4
  var hasRequiredSettings;
@@ -1,4 +1,4 @@
1
- import { __exports as out } from '../../../../../../../_virtual/index11.mjs';
1
+ import { __exports as out } from '../../../../../../../_virtual/index10.mjs';
2
2
  import { __require as requireAsync } from './providers/async.mjs';
3
3
  import { __require as requireStream } from './providers/stream.mjs';
4
4
  import { __require as requireSync } from './providers/sync.mjs';
@@ -1,4 +1,4 @@
1
- import { __exports as async } from '../../../../../../../../_virtual/async4.mjs';
1
+ import { __exports as async } from '../../../../../../../../_virtual/async3.mjs';
2
2
  import { __require as requireAsync$1 } from '../readers/async.mjs';
3
3
 
4
4
  var hasRequiredAsync;
@@ -1,4 +1,4 @@
1
- import { __exports as sync } from '../../../../../../../../_virtual/sync4.mjs';
1
+ import { __exports as sync } from '../../../../../../../../_virtual/sync3.mjs';
2
2
  import { __require as requireSync$1 } from '../readers/sync.mjs';
3
3
 
4
4
  var hasRequiredSync;
@@ -1,4 +1,4 @@
1
- import { __exports as settings } from '../../../../../../../_virtual/settings3.mjs';
1
+ import { __exports as settings } from '../../../../../../../_virtual/settings2.mjs';
2
2
  import path__default from 'node:path';
3
3
  import { __require as requireOut } from '../../../../../@nodelib_fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/index.mjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { __exports as prompts } from '../../../../../../_virtual/prompts.mjs';
1
+ import { __exports as prompts } from '../../../../../../_virtual/prompts2.mjs';
2
2
  import { __require as requireElements } from './elements/index.mjs';
3
3
 
4
4
  var hasRequiredPrompts;
@@ -1,4 +1,4 @@
1
- import { __exports as prompts } from '../../../../../../_virtual/prompts2.mjs';
1
+ import { __exports as prompts } from '../../../../../../_virtual/prompts.mjs';
2
2
  import { __require as requireElements } from './elements/index.mjs';
3
3
 
4
4
  var hasRequiredPrompts;
@@ -1,3 +1,3 @@
1
- var dirGlob = {exports: {}};
1
+ var utils = {};
2
2
 
3
- export { dirGlob as __module };
3
+ export { utils as __exports };
@@ -1,3 +1,3 @@
1
- var utils = {};
1
+ var dirGlob = {exports: {}};
2
2
 
3
- export { utils as __exports };
3
+ export { dirGlob as __module };
@@ -1,4 +1,4 @@
1
- import { __module as dirGlob } from '../../../../../_virtual/index7.esnext';
1
+ import { __module as dirGlob } from '../../../../../_virtual/index8.esnext';
2
2
  import path__default from 'node:path';
3
3
  import { __require as requirePathType } from '../../../path-type@4.0.0/node_modules/path-type/index.esnext';
4
4
 
@@ -1,4 +1,4 @@
1
- import { __exports as utils } from '../../../../../../../_virtual/index8.esnext';
1
+ import { __exports as utils } from '../../../../../../../_virtual/index7.esnext';
2
2
  import { __require as requireArray } from './array.esnext';
3
3
  import { __require as requireErrno } from './errno.esnext';
4
4
  import { __require as requireFs } from './fs.esnext';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@quilted/create",
3
3
  "type": "module",
4
- "version": "0.2.47",
4
+ "version": "0.2.48",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -1,19 +1,50 @@
1
1
  import '@quilted/quilt/globals';
2
+ import type {ComponentChild} from 'preact';
2
3
  import {hydrate} from '@quilted/quilt/browser';
3
4
  import {Router} from '@quilted/quilt/navigation';
4
5
 
5
6
  import type {AppContext} from '~/shared/context.ts';
6
7
  import {App} from './App.tsx';
7
8
 
8
- const context = {
9
- router: new Router(),
10
- } satisfies AppContext;
9
+ class BrowserAppContext implements AppContext {
10
+ readonly router: Router;
11
11
 
12
- // Makes key parts of the app available in the browser console
13
- Object.defineProperty(globalThis, 'app', {
14
- value: {context},
15
- enumerable: false,
16
- configurable: true,
17
- });
12
+ constructor() {
13
+ this.router = new Router();
14
+ }
15
+ }
18
16
 
19
- hydrate(<App context={context} />);
17
+ class BrowserApp {
18
+ /**
19
+ * The app’s globally-available context.
20
+ */
21
+ readonly context: BrowserAppContext;
22
+
23
+ /**
24
+ * The app’s root JSX element, seeded with the necessary app context.
25
+ */
26
+ readonly rendered: ComponentChild;
27
+
28
+ constructor() {
29
+ this.context = new BrowserAppContext();
30
+ this.rendered = <App context={this.context} />;
31
+
32
+ // Makes key parts of the app available in the browser console.
33
+ //
34
+ // @example
35
+ // ```js
36
+ // // Log the current URL
37
+ // console.log(globalThis.app.context.router.currentRequest.url);
38
+ // ```
39
+ Object.defineProperty(globalThis, 'app', {
40
+ value: this,
41
+ enumerable: false,
42
+ configurable: true,
43
+ writable: true,
44
+ });
45
+ }
46
+ }
47
+
48
+ const app = new BrowserApp();
49
+
50
+ hydrate(app.rendered);
@@ -20,11 +20,17 @@ import {App} from './App.tsx';
20
20
  const router = new RequestRouter();
21
21
  const assets = new BrowserAssets();
22
22
 
23
+ class ServerAppContext implements AppContext {
24
+ readonly router: Router;
25
+
26
+ constructor(request: Request) {
27
+ this.router = new Router(request.url);
28
+ }
29
+ }
30
+
23
31
  // For all GET requests, render our Preact application.
24
32
  router.get(async (request) => {
25
- const context = {
26
- router: new Router(request.url),
27
- } satisfies AppContext;
33
+ const context = new ServerAppContext(request);
28
34
 
29
35
  const isHttps = request.url.startsWith('https://');
30
36
 
@@ -1,5 +1,5 @@
1
1
  import '@quilted/quilt/globals';
2
-
2
+ import type {ComponentChild} from 'preact';
3
3
  import {hydrate} from '@quilted/quilt/browser';
4
4
  import {Router} from '@quilted/quilt/navigation';
5
5
  import {createGraphQLFetch, GraphQLCache} from '@quilted/quilt/graphql';
@@ -8,22 +8,54 @@ import type {AppContext} from '~/shared/context.ts';
8
8
 
9
9
  import {App} from './App.tsx';
10
10
 
11
- const graphQLFetch = createGraphQLFetch({url: '/api/graphql'});
12
- const graphQLCache = new GraphQLCache({fetch: graphQLFetch});
13
-
14
- const context = {
15
- router: new Router(),
16
- graphql: {
17
- fetch: graphQLFetch,
18
- cache: graphQLCache,
19
- },
20
- } satisfies AppContext;
21
-
22
- // Makes key parts of the app available in the browser console
23
- Object.defineProperty(globalThis, 'app', {
24
- value: {context},
25
- enumerable: false,
26
- configurable: true,
27
- });
28
-
29
- hydrate(<App context={context} />);
11
+ class BrowserAppContext implements AppContext {
12
+ readonly router: Router;
13
+ readonly graphql: AppContext['graphql'];
14
+
15
+ constructor() {
16
+ this.router = new Router();
17
+
18
+ const graphQLFetch = createGraphQLFetch({url: '/api/graphql'});
19
+ const graphQLCache = new GraphQLCache({fetch: graphQLFetch});
20
+
21
+ this.graphql = {
22
+ fetch: graphQLFetch,
23
+ cache: graphQLCache,
24
+ };
25
+ }
26
+ }
27
+
28
+ class BrowserApp {
29
+ /**
30
+ * The app's globally-available context.
31
+ */
32
+ readonly context: BrowserAppContext;
33
+
34
+ /**
35
+ * The app's root JSX element, seeded with the necessary app context.
36
+ */
37
+ readonly rendered: ComponentChild;
38
+
39
+ constructor() {
40
+ this.context = new BrowserAppContext();
41
+ this.rendered = <App context={this.context} />;
42
+
43
+ // Makes key parts of the app available in the browser console.
44
+ //
45
+ // @example
46
+ // ```js
47
+ // // Log the current URL
48
+ // console.log(globalThis.app.context.router.currentRequest.url);
49
+ // ```
50
+ Object.defineProperty(globalThis, 'app', {
51
+ value: this,
52
+ enumerable: false,
53
+ configurable: true,
54
+ writable: true,
55
+ });
56
+ }
57
+ }
58
+
59
+ const app = new BrowserApp();
60
+
61
+ hydrate(app.rendered);
@@ -9,6 +9,7 @@ import {
9
9
  permissionsPolicyHeader,
10
10
  strictTransportSecurityHeader,
11
11
  } from '@quilted/quilt/server';
12
+ import {GraphQLCache} from '@quilted/quilt/graphql';
12
13
 
13
14
  import Env from 'quilt:module/env';
14
15
  import {BrowserAssets} from 'quilt:module/assets';
@@ -18,6 +19,25 @@ import type {AppContext} from '~/shared/context.ts';
18
19
  const router = new RequestRouter();
19
20
  const assets = new BrowserAssets();
20
21
 
22
+ class ServerAppContext implements AppContext {
23
+ readonly router: Router;
24
+ readonly graphql: AppContext['graphql'];
25
+
26
+ constructor(request: Request) {
27
+ this.router = new Router(request.url);
28
+
29
+ const graphQLFetch: AppContext['graphql']['fetch'] = async (...args) => {
30
+ const {performGraphQLOperation} = await import('./server/graphql.ts');
31
+ return performGraphQLOperation(...args);
32
+ };
33
+
34
+ this.graphql = {
35
+ fetch: graphQLFetch,
36
+ cache: new GraphQLCache({fetch: graphQLFetch}),
37
+ };
38
+ }
39
+ }
40
+
21
41
  // GraphQL API, called from the client
22
42
  router.post('/api/graphql', async (request) => {
23
43
  const [{query, operationName, variables}, {performGraphQLOperation}] =
@@ -33,19 +53,9 @@ router.post('/api/graphql', async (request) => {
33
53
 
34
54
  // For all GET requests, render our Preact application.
35
55
  router.get(async (request) => {
36
- const [{App}, {performGraphQLOperation}, {GraphQLCache}] = await Promise.all([
37
- import('./App.tsx'),
38
- import('./server/graphql.ts'),
39
- import('@quilted/quilt/graphql'),
40
- ]);
41
-
42
- const context = {
43
- router: new Router(request.url),
44
- graphql: {
45
- fetch: performGraphQLOperation,
46
- cache: new GraphQLCache({fetch: performGraphQLOperation}),
47
- },
48
- } satisfies AppContext;
56
+ const [{App}] = await Promise.all([import('./App.tsx')]);
57
+
58
+ const context = new ServerAppContext(request);
49
59
 
50
60
  const isHttps = request.url.startsWith('https://');
51
61
 
@@ -1,6 +1,14 @@
1
1
  import {createOptionalContext} from '@quilted/quilt/context';
2
+ import type {Router} from '@quilted/quilt/navigation';
3
+ import type {GraphQLFetch, GraphQLCache} from '@quilted/quilt/graphql';
2
4
 
3
- export interface AppContext {}
5
+ export interface AppContext {
6
+ readonly router: Router;
7
+ readonly graphql: {
8
+ readonly fetch: GraphQLFetch<any>;
9
+ readonly cache: GraphQLCache;
10
+ };
11
+ }
4
12
 
5
13
  export const AppContextReact = createOptionalContext<AppContext>();
6
14
  export const useAppContext = AppContextReact.use;
@@ -1,5 +1,5 @@
1
1
  import '@quilted/quilt/globals';
2
-
2
+ import type {ComponentChild} from 'preact';
3
3
  import {hydrate} from '@quilted/quilt/browser';
4
4
  import {Router} from '@quilted/quilt/navigation';
5
5
 
@@ -11,22 +11,51 @@ import {trpc} from '~/shared/trpc.ts';
11
11
 
12
12
  import {App} from './App.tsx';
13
13
 
14
- const queryClient = new QueryClient();
15
- const trpcClient = trpc.createClient({
16
- links: [httpBatchLink({url: new URL('/api', window.location.href).href})],
17
- });
18
-
19
- const context = {
20
- router: new Router(),
21
- trpc: trpcClient,
22
- queryClient,
23
- } satisfies AppContext;
24
-
25
- // Makes key parts of the app available in the browser console
26
- Object.defineProperty(globalThis, 'app', {
27
- value: {context},
28
- enumerable: false,
29
- configurable: true,
30
- });
31
-
32
- hydrate(<App context={context} />);
14
+ class BrowserAppContext implements AppContext {
15
+ readonly router: Router;
16
+ readonly trpc: AppContext['trpc'];
17
+ readonly queryClient: QueryClient;
18
+
19
+ constructor() {
20
+ this.router = new Router();
21
+ this.queryClient = new QueryClient();
22
+ this.trpc = trpc.createClient({
23
+ links: [httpBatchLink({url: new URL('/api', window.location.href).href})],
24
+ });
25
+ }
26
+ }
27
+
28
+ class BrowserApp {
29
+ /**
30
+ * The app's globally-available context.
31
+ */
32
+ readonly context: BrowserAppContext;
33
+
34
+ /**
35
+ * The app's root JSX element, seeded with the necessary app context.
36
+ */
37
+ readonly rendered: ComponentChild;
38
+
39
+ constructor() {
40
+ this.context = new BrowserAppContext();
41
+ this.rendered = <App context={this.context} />;
42
+
43
+ // Makes key parts of the app available in the browser console.
44
+ //
45
+ // @example
46
+ // ```js
47
+ // // Log the current URL
48
+ // console.log(globalThis.app.context.router.currentRequest.url);
49
+ // ```
50
+ Object.defineProperty(globalThis, 'app', {
51
+ value: this,
52
+ enumerable: false,
53
+ configurable: true,
54
+ writable: true,
55
+ });
56
+ }
57
+ }
58
+
59
+ const app = new BrowserApp();
60
+
61
+ hydrate(app.rendered);
@@ -15,6 +15,7 @@ import {BrowserAssets} from 'quilt:module/assets';
15
15
 
16
16
  import {createDirectClient} from '@quilted/trpc/server';
17
17
  import {fetchRequestHandler} from '@trpc/server/adapters/fetch';
18
+ import {QueryClient} from '@tanstack/react-query';
18
19
 
19
20
  import type {AppContext} from '~/shared/context.ts';
20
21
 
@@ -23,6 +24,18 @@ import {appRouter} from './trpc.ts';
23
24
  const router = new RequestRouter();
24
25
  const assets = new BrowserAssets();
25
26
 
27
+ class ServerAppContext implements AppContext {
28
+ readonly router: Router;
29
+ readonly trpc: AppContext['trpc'];
30
+ readonly queryClient: QueryClient;
31
+
32
+ constructor(request: Request) {
33
+ this.router = new Router(request.url);
34
+ this.trpc = createDirectClient(appRouter);
35
+ this.queryClient = new QueryClient();
36
+ }
37
+ }
38
+
26
39
  router.any(
27
40
  'api',
28
41
  (request) => {
@@ -38,16 +51,9 @@ router.any(
38
51
 
39
52
  // For all GET requests, render our React application.
40
53
  router.get(async (request) => {
41
- const [{App}, {QueryClient}] = await Promise.all([
42
- import('./App.tsx'),
43
- import('@tanstack/react-query'),
44
- ]);
45
-
46
- const context = {
47
- router: new Router(request.url),
48
- trpc: createDirectClient(appRouter),
49
- queryClient: new QueryClient(),
50
- } satisfies AppContext;
54
+ const [{App}] = await Promise.all([import('./App.tsx')]);
55
+
56
+ const context = new ServerAppContext(request);
51
57
 
52
58
  const isHttps = request.url.startsWith('https://');
53
59