eddev 2.0.0-beta.31 → 2.0.0-beta.33

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.
@@ -1,7 +1,7 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useRef, useState } from "react";
3
- import { useTailwindConfig } from "../hooks/useTailwind.js";
4
3
  import { usePersistState } from "../hooks/usePersistState.js";
4
+ import { useTailwindConfig } from "../hooks/useTailwind.js";
5
5
  function parseBreakpointMin(breakpoint) {
6
6
  return parseInt(breakpoint);
7
7
  }
@@ -1,6 +1,7 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import "../../../../../css/devtools.css";
3
3
  import { BreakpointIndicator } from "./BreakpointIndicator.js";
4
+ import { GridIndicator } from "./GridIndicator";
4
5
  export default function DevUI() {
5
- return (_jsx("div", { className: "eddev-ui", children: _jsx(BreakpointIndicator, {}) }));
6
+ return (_jsxs("div", { className: "eddev-ui", children: [_jsx(BreakpointIndicator, {}), _jsx(GridIndicator, {})] }));
6
7
  }
@@ -0,0 +1 @@
1
+ export declare function GridIndicator(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect } from "react";
3
+ import { usePersistState } from "../hooks/usePersistState.js";
4
+ export function GridIndicator() {
5
+ const [enabled, setEnabled] = usePersistState("gridOverlayEnabled", false);
6
+ useEffect(() => {
7
+ const handleKeyDown = (e) => {
8
+ if (e.key === "g" && e.ctrlKey) {
9
+ setEnabled((e) => !e);
10
+ }
11
+ };
12
+ window.addEventListener("keydown", handleKeyDown);
13
+ return () => {
14
+ window.removeEventListener("keydown", handleKeyDown);
15
+ };
16
+ }, []);
17
+ const cols = [];
18
+ for (let i = 0; i < 12; i++) {
19
+ cols.push(_jsx("div", { style: { height: "100%", backgroundColor: "rgba(255,0,0,0.1)" } }));
20
+ }
21
+ if (!enabled)
22
+ return null;
23
+ return (_jsx("div", { style: { position: "fixed", inset: 0, zIndex: 999999999, pointerEvents: "none" }, children: _jsx("div", { className: "grid-auto", style: { height: "100%" }, children: cols }) }));
24
+ }
@@ -1 +1 @@
1
- export declare function usePersistState<T>(id: string, initial: T): [T, (value: T) => void];
1
+ export declare function usePersistState<T>(id: string, initial: T): [T, (value: T | ((current: T) => T)) => void];
@@ -24,8 +24,17 @@ export function usePersistState(id, initial) {
24
24
  return [
25
25
  value,
26
26
  (value) => {
27
- set(id, value);
28
- setValue(value);
27
+ if (typeof value === "function") {
28
+ return setValue((cur) => {
29
+ const next = value(cur);
30
+ set(id, next);
31
+ return next;
32
+ });
33
+ }
34
+ else {
35
+ set(id, value);
36
+ setValue(value);
37
+ }
29
38
  },
30
39
  ];
31
40
  }
@@ -1,14 +1,15 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect } from "react";
3
- import { dynamic } from "../dynamic/dynamic.js";
2
+ import { lazy, useEffect } from "react";
4
3
  import { usePersistState } from "./hooks/usePersistState.js";
5
4
  import { useIsSSR } from "../routing/hooks/useIsSSR.js";
6
- const DevUI = dynamic(() => import("./components/DevUI.js"));
5
+ const DevUI = lazy(() => import("./components/DevUI.js"));
7
6
  export function DevUILoader() {
8
7
  const ssr = useIsSSR();
9
- const [render, setRender] = usePersistState("enable_devui", typeof window !== "undefined" && (env.dev || window["ENABLE_DEV_UI"]));
8
+ const [render, setRender] = usePersistState("enable_devui", false);
10
9
  useEffect(() => {
11
- if (document.location.search.includes("activate-dev-ui")) {
10
+ if (document.location.search.includes("activate-dev-ui") ||
11
+ window["ENABLE_DEV_UI"] ||
12
+ (env.client && env.dev)) {
12
13
  setRender(true);
13
14
  }
14
15
  }, []);
@@ -6,11 +6,15 @@ import { SSRRoot } from "../entry/ssr-root.js";
6
6
  import { RouteLoader } from "../lib/routing/loader.js";
7
7
  export async function renderPageToSSRStream(pathname, initialData, serverContext) {
8
8
  const clientManifest = serverContext.runtime.getManifest("client");
9
+ // console.log("Rendering to SSR Stream, get assets")
9
10
  const assets = await clientManifest.inputs[clientManifest.handler].assets();
11
+ // console.log("Got assets", assets)
10
12
  const jsx = (_jsx(SSRRoot, { assets: _jsx(Suspense, { children: assets.map((m) => renderAsset(m)) }), metaTags: initialData?.meta?.head || [], pathname: pathname, initialData: initialData, loader: new RouteLoader() }));
11
13
  const stream = await new Promise(async (resolve, reject) => {
14
+ // console.log("Rendering to pipable")
12
15
  const stream = renderToPipeableStream(jsx, {
13
16
  onShellReady() {
17
+ // console.log("Shell ready")
14
18
  resolve(stream);
15
19
  },
16
20
  onShellError(err) {
@@ -76,7 +76,8 @@ export class ServerContext {
76
76
  _ssr: "1",
77
77
  _debug: this.dev ? "1" : undefined,
78
78
  });
79
- return this.fetchOrigin(fetchUrl, {
79
+ // console.log("Fetching route data", req.pathname)
80
+ const result = this.fetchOrigin(fetchUrl, {
80
81
  cache: "no-cache",
81
82
  replaceUrls: true,
82
83
  headers: {
@@ -85,8 +86,11 @@ export class ServerContext {
85
86
  ...this.extractRequestHeaders(req.headers),
86
87
  },
87
88
  });
89
+ // console.log("Finished fetching route data")
90
+ return result;
88
91
  }
89
92
  async fetchAppData(req) {
93
+ // console.log("Fetching app data")
90
94
  const response = await this.fetchOrigin("/_appdata", {
91
95
  cache: "no-cache",
92
96
  replaceUrls: true,
@@ -96,7 +100,10 @@ export class ServerContext {
96
100
  ...(req?.headers ? this.extractRequestHeaders(req.headers) : {}),
97
101
  },
98
102
  });
99
- return response.json();
103
+ // console.log("Decoding app data")
104
+ const result = await response.json();
105
+ // console.log("Done with app done")
106
+ return result;
100
107
  }
101
108
  extractRequestHeaders(req) {
102
109
  const headers = {};
@@ -1 +1 @@
1
- export declare const VERSION = "2.0.0-beta.31";
1
+ export declare const VERSION = "2.0.0-beta.33";
@@ -1 +1 @@
1
- export const VERSION = "2.0.0-beta.31";
1
+ export const VERSION = "2.0.0-beta.33";
@@ -25,12 +25,14 @@ export class DevServer {
25
25
  }
26
26
  async start() {
27
27
  console.setWorking(true);
28
+ // console.log("Setting up vinxi codegen")
28
29
  const codegen = createVinxiCodegen({
29
30
  mode: "development",
30
31
  project: this.project,
31
32
  serverless: true,
32
33
  });
33
34
  await codegen.runAndWatch();
35
+ // console.log("Has run once")
34
36
  const app = createVinxiApp({
35
37
  mode: "development",
36
38
  origin: this.origin,
@@ -45,7 +47,9 @@ export class DevServer {
45
47
  process.env.NITRO_PRESET ??
46
48
  process.env.NITRO_TARGET ??
47
49
  (process.versions.bun !== undefined ? "bun" : "node-server");
50
+ // console.log("Ensuring self signed cert")
48
51
  const keys = await ensureSelfSignedCert(this.hostname, this.project.rootDir);
52
+ // console.log("Done")
49
53
  const httpsConfig = {
50
54
  cert: keys.certFile,
51
55
  key: keys.keyFile,
@@ -61,6 +65,7 @@ export class DevServer {
61
65
  devApp = args.devApp;
62
66
  },
63
67
  });
68
+ // console.log("Creating dev server")
64
69
  await createDevServer(app, {
65
70
  force: false,
66
71
  devtools: false,
@@ -71,11 +76,13 @@ export class DevServer {
71
76
  preset: preset,
72
77
  https: httpsConfig,
73
78
  });
79
+ // console.log("Rnning listen hook")
74
80
  // @ts-ignore
75
81
  await app.hooks.callHook("app:dev:server:listener:creating", {
76
82
  app,
77
83
  devApp,
78
84
  });
85
+ // console.log("Creating another listener")
79
86
  const listener = await devApp.listen(this.port, {
80
87
  hostname: this.hostname,
81
88
  port: this.port,
@@ -88,6 +95,7 @@ export class DevServer {
88
95
  devApp,
89
96
  listener,
90
97
  });
98
+ // console.log("Listening")
91
99
  console.setWorking(false);
92
100
  console.setState({
93
101
  serverlessUrl: this.hostOrigin,
@@ -1,4 +1,4 @@
1
- import { code } from "ts-poet";
1
+ import { code, imp } from "ts-poet";
2
2
  import { FSCodegen } from "../utils/fs-codegen.js";
3
3
  export function getVinxiFolder(opts) {
4
4
  return (opts.mode === "development" ? "dev" : "prod") + (opts.serverless ? "" : "-spa");
@@ -410,12 +410,17 @@ export function createVinxiCodegen(opts) {
410
410
  return code /* ts */ `
411
411
  import { viewManifestReader } from 'eddev/_internal'
412
412
  import { dynamic } from 'eddev/dynamic'
413
- const manifest = {${Object.entries(viewManifest.views)
414
- .map(([name, view]) => {
415
- const importStatement = `dynamic(() => import(${JSON.stringify("../../../" + view.fileName)}))`;
416
- return JSON.stringify(view.slug) + ": " + importStatement;
417
- })
418
- .join(",\n")}}
413
+ const manifest = {${Object.entries(viewManifest.views).map(([name, view]) => {
414
+ const src = "../../../" + view.fileName;
415
+ let importStatement;
416
+ if (name.startsWith("_")) {
417
+ importStatement = imp(name + "=" + src);
418
+ }
419
+ else {
420
+ importStatement = code `dynamic(() => import(${JSON.stringify(src)}))`;
421
+ }
422
+ return code `${JSON.stringify(view.slug)}: ${importStatement},\n`;
423
+ })}}
419
424
 
420
425
  viewManifestReader.value = manifest
421
426
 
@@ -1,5 +1,5 @@
1
1
  import { codegen } from "@graphql-codegen/core";
2
- import { Kind } from "graphql";
2
+ import { Kind, visit } from "graphql";
3
3
  import { NoUnusedFragmentsRule, specifiedRules, validate } from "graphql/validation/index.js";
4
4
  import { join, relative, resolve } from "path";
5
5
  import { ProjectEnvUtils } from "../project/env.js";
@@ -62,6 +62,11 @@ export class GraphQLGenerator {
62
62
  this.project = project;
63
63
  this.schemaLoader = new GraphQLSchemaLoader(ProjectEnvUtils.get("DEBUG_GRAPHQL_URL"));
64
64
  this.fileLoader = createGraphQLFileLoader(this.project, [
65
+ {
66
+ baseFolder: "queries/fragments",
67
+ pattern: "**/*.graphql",
68
+ key: "fragments",
69
+ },
65
70
  {
66
71
  baseFolder: "blocks",
67
72
  pattern: "**/*.graphql",
@@ -72,11 +77,6 @@ export class GraphQLGenerator {
72
77
  pattern: "**/*.graphql",
73
78
  key: "views",
74
79
  },
75
- {
76
- baseFolder: "queries/fragments",
77
- pattern: "**/*.graphql",
78
- key: "fragments",
79
- },
80
80
  {
81
81
  baseFolder: "queries",
82
82
  pattern: "**/*.graphql",
@@ -345,6 +345,44 @@ export class GraphQLGenerator {
345
345
  * Use all rules, except for No Unused Fragments — since we prepend those fragments to every test
346
346
  */
347
347
  const validationRules = specifiedRules.filter((rule) => rule !== NoUnusedFragmentsRule);
348
+ /**
349
+ * Get all the base fragment definitions
350
+ */
351
+ const baseFragments = new Map();
352
+ Object.values(graphQLFiles.fragments)
353
+ .map((file) => file?.ast?.definitions ?? [])
354
+ .filter((def) => def.length > 0)
355
+ .flat()
356
+ .filter((n) => n.kind === Kind.FRAGMENT_DEFINITION)
357
+ .forEach((node) => baseFragments.set(node.name.value, node));
358
+ function findFragments(defs, map = new Map()) {
359
+ for (let def of defs) {
360
+ if (def.kind === Kind.FRAGMENT_DEFINITION) {
361
+ map.set(def.name.value, def);
362
+ }
363
+ }
364
+ for (let def of defs) {
365
+ visit(def, {
366
+ FragmentSpread: {
367
+ enter: (node) => {
368
+ const match = baseFragments.get(node.name.value);
369
+ if (match && !map.has(node.name.value)) {
370
+ map.set(node.name.value, match);
371
+ findFragments([match], map);
372
+ }
373
+ },
374
+ },
375
+ });
376
+ }
377
+ return {
378
+ fragments: [...map.values()],
379
+ definitions: defs.filter((n) => n.kind !== Kind.FRAGMENT_DEFINITION),
380
+ };
381
+ }
382
+ /**
383
+ * Only report the same error once (mostly for preventing repeats of the same fragment errors)
384
+ */
385
+ const errorsShown = new Map();
348
386
  /**
349
387
  * Validate everything
350
388
  */
@@ -356,19 +394,25 @@ export class GraphQLGenerator {
356
394
  }
357
395
  else {
358
396
  // Find all fragments
359
- const fragments = Object.values(graphQLFiles.fragments)
360
- .map((file) => file.ast.definitions)
361
- .filter((def) => def.length > 0)
362
- .filter((def) => def !== file.ast.definitions)
363
- .flat();
397
+ const { fragments, definitions } = findFragments(file?.ast?.definitions ?? []);
364
398
  const validationAST = {
365
399
  kind: Kind.DOCUMENT,
366
- definitions: [...fragments, ...file.ast.definitions],
400
+ definitions: [...fragments, ...definitions],
367
401
  loc: file.ast.loc,
368
402
  };
369
403
  const errors = validate(schema, validationAST, validationRules);
370
404
  if (errors.length > 0) {
371
405
  for (let error of errors) {
406
+ if (error.nodes && error.nodes[0]) {
407
+ const node = error.nodes[0];
408
+ if (errorsShown.has(node) && errorsShown.get(node)?.includes(error.message)) {
409
+ continue;
410
+ }
411
+ else {
412
+ errorsShown.set(node, [...(errorsShown.get(node) ?? []), error.message]);
413
+ }
414
+ }
415
+ // console.log(error.nodes?.map((n) => n.kind))
372
416
  report.push(new GraphQLValidationError(error.message, path, error.locations?.[0].line || 1, error.locations?.[0].column || 1, error.source?.body || ""));
373
417
  }
374
418
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eddev",
3
- "version": "2.0.0-beta.31",
3
+ "version": "2.0.0-beta.33",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -102,6 +102,7 @@
102
102
  "obj-console": "^1.0.2",
103
103
  "object-code": "^1.3.3",
104
104
  "qs": "^6.13.0",
105
+ "react-super-seo": "^1.1.9",
105
106
  "ts-poet": "^6.6.0",
106
107
  "ufo": "^1.3.1",
107
108
  "undent": "^0.1.0",