@_tc/template-core 0.2.0-bate.0 → 0.2.0-bate.2

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 (82) hide show
  1. package/.skills/tc-component-usage-skills/reference/template-core-frontend.md +8 -1
  2. package/.skills/tc-generator/SKILL.md +3 -2
  3. package/.skills/tc-generator/reference/example.md +1 -1
  4. package/.skills/tc-generator/reference/project-template/index.js +1 -1
  5. package/.skills/tc-generator/reference/runtime-extensions.md +2 -2
  6. package/AGENT_README.md +11 -3
  7. package/README.md +24 -7
  8. package/cjs/app/controller/view.js +1 -1
  9. package/cjs/app/{extend → extends}/db.js +1 -1
  10. package/cjs/app/extends/localCacheHtmlEtag.js +1 -0
  11. package/cjs/app/extends/render-view.js +1 -0
  12. package/cjs/app/middleware.js +1 -1
  13. package/cjs/app/view/entry.tpl +0 -16
  14. package/cjs/bundler/index.js +1 -1
  15. package/cjs/bundler/state.js +1 -1
  16. package/cjs/bundler/utils.js +3 -3
  17. package/cjs/packages/common/index.js +1 -1
  18. package/cjs/packages/common/string/index.js +1 -1
  19. package/cjs/packages/core/index.js +1 -1
  20. package/cjs/packages/core/loader/controller.js +1 -1
  21. package/cjs/packages/core/loader/extend.js +1 -1
  22. package/cjs/packages/core/loader/middleware.js +1 -1
  23. package/cjs/packages/core/loader/router-schema.js +1 -1
  24. package/cjs/packages/core/loader/router.js +1 -1
  25. package/cjs/packages/core/loader/service.js +1 -1
  26. package/cjs/packages/utils/runFileFn.js +1 -1
  27. package/esm/app/controller/view.js +28 -15
  28. package/esm/app/{extend → extends}/$fetch.js +1 -1
  29. package/esm/app/{extend → extends}/crypto.js +1 -1
  30. package/esm/app/{extend → extends}/db.js +2 -2
  31. package/esm/app/{extend → extends}/generateErrorMessage.js +1 -1
  32. package/esm/app/extends/localCacheHtmlEtag.js +41 -0
  33. package/esm/app/{extend → extends}/logger.js +1 -1
  34. package/esm/app/{extend → extends}/parsingParamsOnUrl.js +1 -1
  35. package/esm/app/extends/render-view.js +18 -0
  36. package/esm/app/middleware.js +8 -12
  37. package/esm/app/view/entry.tpl +0 -16
  38. package/esm/bundler/index.js +6 -6
  39. package/esm/bundler/state.js +5 -1
  40. package/esm/bundler/utils.js +129 -104
  41. package/esm/packages/common/index.js +6 -6
  42. package/esm/packages/common/string/index.js +11 -2
  43. package/esm/packages/core/index.js +34 -28
  44. package/esm/packages/core/loader/controller.js +6 -6
  45. package/esm/packages/core/loader/extend.js +6 -6
  46. package/esm/packages/core/loader/middleware.js +6 -6
  47. package/esm/packages/core/loader/router-schema.js +7 -7
  48. package/esm/packages/core/loader/router.js +13 -13
  49. package/esm/packages/core/loader/service.js +6 -6
  50. package/esm/packages/utils/runFileFn.js +10 -10
  51. package/fe/frontend/src/common/rafTimer.d.ts +7 -0
  52. package/fe/frontend/src/common/rafTimer.js +144 -0
  53. package/fe/frontend/src/index.d.ts +2 -0
  54. package/fe/frontend/src/index.js +2 -1
  55. package/fe/packages/common/string/index.d.ts +9 -0
  56. package/model/packages/common/string/index.d.ts +9 -0
  57. package/package.json +1 -1
  58. package/types/app/extends/localCacheHtmlEtag.d.ts +10 -0
  59. package/types/app/{extend → extends}/render-view.d.ts +1 -1
  60. package/types/app/service/base.d.ts +1 -1
  61. package/types/app/service/project.d.ts +1 -1
  62. package/types/app/type.d.ts +2 -1
  63. package/types/app/typings.d.ts +10 -8
  64. package/types/bundler/state.d.ts +4 -0
  65. package/types/bundler/utils.d.ts +5 -0
  66. package/types/index.d.ts +3 -3
  67. package/types/packages/common/string/index.d.ts +16 -0
  68. package/types/packages/core/loader/extend.d.ts +1 -1
  69. package/types/packages/core/types.d.ts +4 -0
  70. package/cjs/app/extend/render-view.js +0 -1
  71. package/esm/app/extend/render-view.js +0 -25
  72. /package/cjs/app/{extend → extends}/$fetch.js +0 -0
  73. /package/cjs/app/{extend → extends}/crypto.js +0 -0
  74. /package/cjs/app/{extend → extends}/generateErrorMessage.js +0 -0
  75. /package/cjs/app/{extend → extends}/logger.js +0 -0
  76. /package/cjs/app/{extend → extends}/parsingParamsOnUrl.js +0 -0
  77. /package/types/app/{extend → extends}/$fetch.d.ts +0 -0
  78. /package/types/app/{extend → extends}/crypto.d.ts +0 -0
  79. /package/types/app/{extend → extends}/db.d.ts +0 -0
  80. /package/types/app/{extend → extends}/generateErrorMessage.d.ts +0 -0
  81. /package/types/app/{extend → extends}/logger.d.ts +0 -0
  82. /package/types/app/{extend → extends}/parsingParamsOnUrl.d.ts +0 -0
@@ -1,12 +1,12 @@
1
- import { getAppPaths as e } from "../paths.js";
2
- import { loadFileFn as t } from "../../utils/loadFile.js";
3
- import { runFileFn as n } from "../../utils/runFileFn.js";
1
+ import { loadFileFn as e } from "../../utils/loadFile.js";
2
+ import { runFileFn as t } from "../../utils/runFileFn.js";
4
3
  import "../../utils/index.js";
4
+ import { getAppPaths as n } from "../paths.js";
5
5
  //#region packages/core/loader/controller.ts
6
6
  var r = (r) => {
7
- r.controller = e(r).reduce((e, i) => ({
8
- ...e,
9
- ...t(i, "controller", { loadFileCallback: (e) => new (n(e)(r))() })
7
+ r.controller = n(r).reduce((n, i) => ({
8
+ ...n,
9
+ ...e(i, "controller", { loadFileCallback: (e) => new (t(e)(r))() })
10
10
  }), {});
11
11
  };
12
12
  //#endregion
@@ -1,19 +1,19 @@
1
- import { getAppPaths as e } from "../paths.js";
2
- import { loadFileFn as t } from "../../utils/loadFile.js";
3
- import { runFileFn as n } from "../../utils/runFileFn.js";
1
+ import { loadFileFn as e } from "../../utils/loadFile.js";
2
+ import { runFileFn as t } from "../../utils/runFileFn.js";
4
3
  import "../../utils/index.js";
4
+ import { getAppPaths as n } from "../paths.js";
5
5
  //#region packages/core/loader/extend.ts
6
6
  var r = async (r) => {
7
7
  r.extends = { ...r.extends };
8
8
  let i = [];
9
- e(r).forEach((e) => {
10
- t(e, "extend", { processingFileCallback: ((e, t, a) => {
9
+ n(r).forEach((n) => {
10
+ e(n, "extends", { processingFileCallback: ((e, n, a) => {
11
11
  if (!a) {
12
12
  for (let t in r) if (t === e) {
13
13
  console.log("\x1B[31m%s\x1B[0m", `[extend loader error] name:${e} is already in app`);
14
14
  return;
15
15
  }
16
- let a = n(t)(r);
16
+ let a = t(n)(r);
17
17
  i.push(Promise.resolve(a).then((t) => ({
18
18
  fileName: e,
19
19
  value: t
@@ -1,13 +1,13 @@
1
- import { getAppPaths as e } from "../paths.js";
2
- import { loadFileFn as t } from "../../utils/loadFile.js";
3
- import { runFileFn as n } from "../../utils/runFileFn.js";
1
+ import { loadFileFn as e } from "../../utils/loadFile.js";
2
+ import { runFileFn as t } from "../../utils/runFileFn.js";
4
3
  import "../../utils/index.js";
4
+ import { getAppPaths as n } from "../paths.js";
5
5
  //#region packages/core/loader/middleware.ts
6
6
  var r = (r) => {
7
- r.middlewares = e(r).reduce((e, i) => {
8
- let a = t(i, "middlewares", { loadFileCallback: (e) => n(e)(r) });
7
+ r.middlewares = n(r).reduce((n, i) => {
8
+ let a = e(i, "middlewares", { loadFileCallback: (e) => t(e)(r) });
9
9
  return {
10
- ...e,
10
+ ...n,
11
11
  ...a
12
12
  };
13
13
  }, {});
@@ -1,16 +1,16 @@
1
- import { getAppPaths as e } from "../paths.js";
2
- import { resolve as t } from "../../utils/path.js";
3
- import { loadFileFn as n } from "../../utils/loadFile.js";
4
- import { runFileFn as r } from "../../utils/runFileFn.js";
1
+ import { resolve as e } from "../../utils/path.js";
2
+ import { loadFileFn as t } from "../../utils/loadFile.js";
3
+ import { runFileFn as n } from "../../utils/runFileFn.js";
5
4
  import "../../utils/index.js";
5
+ import { getAppPaths as r } from "../paths.js";
6
6
  //#region packages/core/loader/router-schema.ts
7
7
  var i = (i) => {
8
8
  let a = {};
9
- e(i).forEach((e) => {
10
- n(e, "router-schema", { preProcessingFileCallback(e) {
9
+ r(i).forEach((r) => {
10
+ t(r, "router-schema", { preProcessingFileCallback(t) {
11
11
  a = {
12
12
  ...a,
13
- ...r(t(e))
13
+ ...n(e(t))
14
14
  };
15
15
  } });
16
16
  }), i.routerSchema = a;
@@ -1,26 +1,26 @@
1
- import { getAppPath as e, getAppPaths as t } from "../paths.js";
2
- import { resolve as n } from "../../utils/path.js";
3
- import { loadFileFn as r } from "../../utils/loadFile.js";
4
- import { runFileFn as i } from "../../utils/runFileFn.js";
1
+ import { resolve as e } from "../../utils/path.js";
2
+ import { loadFileFn as t } from "../../utils/loadFile.js";
3
+ import { runFileFn as n } from "../../utils/runFileFn.js";
5
4
  import "../../utils/index.js";
5
+ import { getAppPath as r, getAppPaths as i } from "../paths.js";
6
6
  import { existsSync as a } from "fs";
7
7
  import o from "koa-router";
8
8
  //#region packages/core/loader/router.ts
9
9
  var s = (s) => {
10
- let c, l = e(s, "business");
11
- if (l) for (let e of ["router-guard.ts", "router-guard.js"]) {
12
- let t = n(l, e);
13
- if (a(t)) {
14
- c = i(t)(s);
10
+ let c, l = r(s, "business");
11
+ if (l) for (let t of ["router-guard.ts", "router-guard.js"]) {
12
+ let r = e(l, t);
13
+ if (a(r)) {
14
+ c = n(r)(s);
15
15
  break;
16
16
  }
17
17
  }
18
18
  c || console.info("-- [router-guard] -- not router-guard.(ts|js) file");
19
19
  let u = [];
20
- t(s).forEach((e) => {
21
- r(e, "router", { preProcessingFileCallback: (e) => {
22
- let t = new o();
23
- t.level = 0, u.push(t), i(n(e))(s, t);
20
+ i(s).forEach((r) => {
21
+ t(r, "router", { preProcessingFileCallback: (t) => {
22
+ let r = new o();
23
+ r.level = 0, u.push(r), n(e(t))(s, r);
24
24
  } });
25
25
  });
26
26
  let d = new o();
@@ -1,12 +1,12 @@
1
- import { getAppPaths as e } from "../paths.js";
2
- import { loadFileFn as t } from "../../utils/loadFile.js";
3
- import { runFileFn as n } from "../../utils/runFileFn.js";
1
+ import { loadFileFn as e } from "../../utils/loadFile.js";
2
+ import { runFileFn as t } from "../../utils/runFileFn.js";
4
3
  import "../../utils/index.js";
4
+ import { getAppPaths as n } from "../paths.js";
5
5
  //#region packages/core/loader/service.ts
6
6
  var r = (r) => {
7
- r.service = e(r).reduce((e, i) => ({
8
- ...e,
9
- ...t(i, "service", { loadFileCallback: (e) => new (n(e)(r))() })
7
+ r.service = n(r).reduce((n, i) => ({
8
+ ...n,
9
+ ...e(i, "service", { loadFileCallback: (e) => new (t(e)(r))() })
10
10
  }), {});
11
11
  };
12
12
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { __require as e } from "../../_virtual/_rolldown/runtime.js";
2
- import { extname as t } from "path";
3
- import { readFileSync as n } from "fs";
2
+ import { readFileSync as t } from "fs";
3
+ import { extname as n } from "path";
4
4
  //#region packages/utils/runFileFn.ts
5
5
  var r = !1;
6
6
  function i(e) {
@@ -9,12 +9,12 @@ function i(e) {
9
9
  function a(e) {
10
10
  return e && typeof e == "object" && "default" in e && e.default !== void 0 ? e.default : e;
11
11
  }
12
- function o(n) {
12
+ function o(t) {
13
13
  try {
14
- return e(n);
14
+ return e(t);
15
15
  } catch (r) {
16
- if (t(n) !== ".ts" || !s(r)) throw r;
17
- return c(), delete e.cache[e.resolve(n)], e(n);
16
+ if (n(t) !== ".ts" || !s(r)) throw r;
17
+ return c(), delete e.cache[e.resolve(t)], e(t);
18
18
  }
19
19
  }
20
20
  function s(e) {
@@ -23,11 +23,11 @@ function s(e) {
23
23
  }
24
24
  function c() {
25
25
  if (r) return;
26
- let t = l();
26
+ let n = l();
27
27
  e.extensions[".ts"] = (e, r) => {
28
- let { outputText: i } = t.transpileModule(n(r, "utf8"), { compilerOptions: {
29
- module: t.ModuleKind.CommonJS,
30
- target: t.ScriptTarget.ES2020,
28
+ let { outputText: i } = n.transpileModule(t(r, "utf8"), { compilerOptions: {
29
+ module: n.ModuleKind.CommonJS,
30
+ target: n.ScriptTarget.ES2020,
31
31
  esModuleInterop: !0,
32
32
  allowSyntheticDefaultImports: !0
33
33
  } });
@@ -0,0 +1,7 @@
1
+ export type RafTimerId = number;
2
+ export type RafTimerCallback<Args extends unknown[] = []> = (...args: Args) => void;
3
+ export declare const rafSetTimeout: <Args extends unknown[]>(callback: RafTimerCallback<Args>, delay?: number, ...args: Args) => RafTimerId;
4
+ export declare const rafClearTimeout: (timerId: RafTimerId) => void;
5
+ export declare const rafSetInterval: <Args extends unknown[]>(callback: RafTimerCallback<Args>, delay?: number, ...args: Args) => RafTimerId;
6
+ export declare const rafClearInterval: (timerId: RafTimerId) => void;
7
+ export declare const clearRafTimer: (timerId: RafTimerId) => void;
@@ -0,0 +1,144 @@
1
+ //#region frontend/src/common/rafTimer.ts
2
+ var rafTimers = /* @__PURE__ */ new Map();
3
+ var rafTimerSeed = 0;
4
+ /**
5
+ * 统一修正延迟时间,避免传入 undefined 或负数。
6
+ *
7
+ * @param delay 原始延迟时间。
8
+ * @returns 不小于 0 的延迟时间。
9
+ */
10
+ var normalizeDelay = (delay) => Math.max(0, delay ?? 0);
11
+ /**
12
+ * 确认当前环境支持 requestAnimationFrame。
13
+ */
14
+ var assertRafAvailable = () => {
15
+ if (typeof requestAnimationFrame === "undefined" || typeof cancelAnimationFrame === "undefined") throw new Error("raf timer requires requestAnimationFrame and can only run in a browser environment.");
16
+ };
17
+ /**
18
+ * 创建唯一的计时器 id。
19
+ *
20
+ * @returns 新的计时器 id。
21
+ */
22
+ var createTimerId = () => {
23
+ rafTimerSeed += 1;
24
+ return rafTimerSeed;
25
+ };
26
+ /**
27
+ * 删除并取消指定计时器。
28
+ *
29
+ * 步骤:
30
+ * 1. 根据 id 查找计时器状态。
31
+ * 2. 如果计时器不存在,直接结束。
32
+ * 3. 取消下一帧回调,并从缓存中移除计时器。
33
+ *
34
+ * @param timerId 要取消的计时器 id。
35
+ */
36
+ var deleteTimer = (timerId) => {
37
+ const timer = rafTimers.get(timerId);
38
+ if (!timer) return;
39
+ cancelAnimationFrame(timer.frameId);
40
+ rafTimers.delete(timerId);
41
+ };
42
+ /**
43
+ * 每一帧执行一次的调度函数。
44
+ *
45
+ * 步骤:
46
+ * 1. 读取当前计时器状态。
47
+ * 2. 对比当前时间和起始时间/上次执行时间,判断是否到达延迟。
48
+ * 3. timeout 到点后执行一次并删除计时器。
49
+ * 4. interval 到点后执行回调,并更新上次执行时间。
50
+ * 5. 如果计时器仍然存在,继续注册下一帧。
51
+ *
52
+ * @param timerId 当前计时器 id。
53
+ * @param currentTime requestAnimationFrame 传入的当前时间戳。
54
+ */
55
+ var tick = (timerId, currentTime) => {
56
+ const timer = rafTimers.get(timerId);
57
+ if (!timer) return;
58
+ if (timer.type === "timeout" ? currentTime - timer.startTime >= timer.delay : currentTime - timer.lastRunTime >= timer.delay) {
59
+ if (timer.type === "timeout") {
60
+ rafTimers.delete(timerId);
61
+ timer.callback();
62
+ return;
63
+ }
64
+ timer.lastRunTime = currentTime;
65
+ timer.callback();
66
+ }
67
+ if (rafTimers.has(timerId)) timer.frameId = requestAnimationFrame((nextTime) => tick(timerId, nextTime));
68
+ };
69
+ /**
70
+ * 创建 requestAnimationFrame 计时器。
71
+ *
72
+ * 步骤:
73
+ * 1. 检查当前运行环境是否支持 requestAnimationFrame。
74
+ * 2. 创建计时器 id,并记录起始时间。
75
+ * 3. 保存计时器类型、延迟、回调和帧 id 等状态。
76
+ * 4. 注册第一帧调度。
77
+ * 5. 将计时器状态写入缓存,并返回计时器 id。
78
+ *
79
+ * @param type 计时器类型。
80
+ * @param callback 到点后执行的回调函数。
81
+ * @param delay 延迟或间隔时间,单位毫秒。
82
+ * @param args 传给回调函数的参数。
83
+ * @returns 计时器 id。
84
+ */
85
+ var createRafTimer = (type, callback, delay, args) => {
86
+ assertRafAvailable();
87
+ const timerId = createTimerId();
88
+ const startTime = performance.now();
89
+ const timer = {
90
+ type,
91
+ delay: normalizeDelay(delay),
92
+ callback: () => callback(...args ?? []),
93
+ startTime,
94
+ lastRunTime: startTime,
95
+ frameId: 0
96
+ };
97
+ timer.frameId = requestAnimationFrame((currentTime) => tick(timerId, currentTime));
98
+ rafTimers.set(timerId, timer);
99
+ return timerId;
100
+ };
101
+ /**
102
+ * 使用 requestAnimationFrame 驱动,在指定延迟后执行一次回调。
103
+ *
104
+ * @param callback 延迟结束后执行的回调函数。
105
+ * @param delay 延迟时间,单位毫秒,默认 0。
106
+ * @param args 传给回调函数的参数。
107
+ * @returns 计时器 id,可通过 rafClearTimeout 或 clearRafTimer 取消。
108
+ */
109
+ var rafSetTimeout = (callback, delay, ...args) => createRafTimer("timeout", callback, delay, args);
110
+ /**
111
+ * 取消 rafSetTimeout 创建的计时器。
112
+ *
113
+ * @param timerId rafSetTimeout 返回的计时器 id。
114
+ */
115
+ var rafClearTimeout = (timerId) => {
116
+ deleteTimer(timerId);
117
+ };
118
+ /**
119
+ * 使用 requestAnimationFrame 驱动,按指定间隔重复执行回调。
120
+ *
121
+ * @param callback 每次间隔结束后执行的回调函数。
122
+ * @param delay 间隔时间,单位毫秒,默认 0。
123
+ * @param args 传给回调函数的参数。
124
+ * @returns 计时器 id,可通过 rafClearInterval 或 clearRafTimer 取消。
125
+ */
126
+ var rafSetInterval = (callback, delay, ...args) => createRafTimer("interval", callback, delay, args);
127
+ /**
128
+ * 取消 rafSetInterval 创建的计时器。
129
+ *
130
+ * @param timerId rafSetInterval 返回的计时器 id。
131
+ */
132
+ var rafClearInterval = (timerId) => {
133
+ deleteTimer(timerId);
134
+ };
135
+ /**
136
+ * 取消本模块创建的任意 requestAnimationFrame 计时器。
137
+ *
138
+ * @param timerId rafSetTimeout 或 rafSetInterval 返回的计时器 id。
139
+ */
140
+ var clearRafTimer = (timerId) => {
141
+ deleteTimer(timerId);
142
+ };
143
+ //#endregion
144
+ export { clearRafTimer, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout };
@@ -6,6 +6,8 @@ export * from "./components/index";
6
6
  export type { FormFieldSchema, SchemaFormComponentsMap, SchemaFormNamespace, SelectProps } from "../../packages/react/ui/index";
7
7
  export { api, del, get, patch, post, put, request } from "./common/request";
8
8
  export type { AxiosError, BaseResponse, PageParams, PageResponse, RequestConfig, ResponseConfig } from "./common/request";
9
+ export { clearRafTimer, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout } from "./common/rafTimer";
10
+ export type { RafTimerCallback, RafTimerId } from "./common/rafTimer";
9
11
  export * from "./defaultPages/SchemaPage/data/eventInfo";
10
12
  export { merge } from "./defaultPages/SchemaPage/utils/permissions";
11
13
  export * from "./exportStore";
@@ -10,6 +10,7 @@ import { schemaEventBus } from "./stores/schemaEventBus.js";
10
10
  import { schemaStore, useSchemaStore } from "./stores/schemaStore.js";
11
11
  import "./exportStore.js";
12
12
  import { initApp } from "./main.js";
13
+ import { clearRafTimer, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout } from "./common/rafTimer.js";
13
14
  import AsyncSelect_default from "./components/AsyncSelect/index.js";
14
15
  import LanguageSwitch_default from "./components/LanguageSwitch/index.js";
15
16
  import { themeSwitchStorageKey } from "./components/ThemeSwitch/ThemeSwitch.js";
@@ -17,4 +18,4 @@ import ThemeSwitch_default from "./components/ThemeSwitch/index.js";
17
18
  import "./components/index.js";
18
19
  import { eventsInfo } from "./defaultPages/SchemaPage/data/eventInfo.js";
19
20
  import { merge } from "./defaultPages/SchemaPage/utils/permissions.js";
20
- export { AsyncSelect_default as AsyncSelect, FreezeState, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, api, apiFreezerStore, del, eventsInfo, generateRouter, get, getAuthToken, i18n, i18nStore, initApp, localKeyMap, merge, modeStore, patch, post, put, request, schemaEventBus, schemaStore, setAuthToken, themeSwitchStorageKey, useApiFreezer, useModeStore, useSchemaStore };
21
+ export { AsyncSelect_default as AsyncSelect, FreezeState, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, api, apiFreezerStore, clearRafTimer, del, eventsInfo, generateRouter, get, getAuthToken, i18n, i18nStore, initApp, localKeyMap, merge, modeStore, patch, post, put, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, request, schemaEventBus, schemaStore, setAuthToken, themeSwitchStorageKey, useApiFreezer, useModeStore, useSchemaStore };
@@ -1,3 +1,12 @@
1
1
  export declare const isBlank: (value: string | null | undefined) => boolean;
2
2
  export declare const capitalize: (value: string) => string;
3
3
  export declare const kebabCase: (value: string) => string;
4
+ type JoinStrValue = string | number | boolean | null | undefined;
5
+ type JoinStrConditionalValue = readonly [condition: unknown, value: JoinStrValue];
6
+ type JoinStrInput = JoinStrValue | JoinStrConditionalValue;
7
+ type JoinStrOptions = {
8
+ separator?: string;
9
+ };
10
+ type JoinStrArgs = readonly JoinStrInput[] | readonly [...JoinStrInput[], JoinStrOptions];
11
+ export declare const joinStr: (...strings: JoinStrArgs) => string;
12
+ export {};
@@ -1,3 +1,12 @@
1
1
  export declare const isBlank: (value: string | null | undefined) => boolean;
2
2
  export declare const capitalize: (value: string) => string;
3
3
  export declare const kebabCase: (value: string) => string;
4
+ type JoinStrValue = string | number | boolean | null | undefined;
5
+ type JoinStrConditionalValue = readonly [condition: unknown, value: JoinStrValue];
6
+ type JoinStrInput = JoinStrValue | JoinStrConditionalValue;
7
+ type JoinStrOptions = {
8
+ separator?: string;
9
+ };
10
+ type JoinStrArgs = readonly JoinStrInput[] | readonly [...JoinStrInput[], JoinStrOptions];
11
+ export declare const joinStr: (...strings: JoinStrArgs) => string;
12
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_tc/template-core",
3
- "version": "0.2.0-bate.0",
3
+ "version": "0.2.0-bate.2",
4
4
  "description": "A full-stack TypeScript admin framework powered by Koa, React, and Vite - monorepo root",
5
5
  "types": "./types/index.d.ts",
6
6
  "exports": {
@@ -0,0 +1,10 @@
1
+ /**
2
+ * htmlEtag本地储存
3
+ */
4
+ declare const localCacheHtmlEtag: (app: import("../../packages/core/index").KoaApp) => {
5
+ keepFreshFEBuildKey: () => void;
6
+ hasEtag: (key: string) => boolean;
7
+ getEtag: (key: string) => string | null;
8
+ setEtag: (key: string, value: string) => void;
9
+ };
10
+ export default localCacheHtmlEtag;
@@ -3,5 +3,5 @@ import type { Ctx, KoaApp } from "../type";
3
3
  * 挂载模板资源地址 默认是 public/dist 目录
4
4
  *
5
5
  */
6
- declare const _default: (app: KoaApp) => (view: string, ctx: Ctx, context?: Record<string, unknown>) => void;
6
+ declare const _default: (app: KoaApp) => (viewPath: string, ctx: Ctx, context?: Record<string, unknown>) => string;
7
7
  export default _default;
@@ -3,7 +3,7 @@ declare const getBaseService: (app: KoaApp) => {
3
3
  new (): {
4
4
  get app(): KoaApp;
5
5
  get config(): KoaApp["config"];
6
- get curl(): import("../extend/$fetch").NodeFetch;
6
+ get curl(): import("../extends/$fetch").NodeFetch;
7
7
  };
8
8
  };
9
9
  export default getBaseService;
@@ -51,7 +51,7 @@ declare const getProjectService: (app: KoaApp) => {
51
51
  getProject: (projectKey: string) => ProjectItem | null;
52
52
  get app(): KoaApp;
53
53
  get config(): KoaApp["config"];
54
- get curl(): import("../extend/$fetch").NodeFetch;
54
+ get curl(): import("../extends/$fetch").NodeFetch;
55
55
  };
56
56
  };
57
57
  export default getProjectService;
@@ -1,6 +1,6 @@
1
+ import type { IncomingHttpHeaders } from "http";
1
2
  import type Koa from "koa";
2
3
  import type Router from "koa-router";
3
- import type { IncomingHttpHeaders } from "http";
4
4
  import type { ParsedUrlQuery } from "querystring";
5
5
  export type KoaApp = import('./typings').KoaApp;
6
6
  export type KoaRouter = import('./typings').KoaRouter;
@@ -28,6 +28,7 @@ export type Ctx = Router.RouterContext<Koa.DefaultState, Koa.DefaultContext> & {
28
28
  params: CtxParams;
29
29
  reqData?: CtxReqData;
30
30
  };
31
+ export type ExtendFN<T extends object = object> = (app: KoaApp) => T;
31
32
  export type MiddlewareFN = (app: KoaApp) => (ctx: Ctx, next: Koa.Next) => Promise<void>;
32
33
  export type RouterFN = (app: KoaApp, router: KoaRouter) => void;
33
34
  export type ControllerFN<T extends object = object> = (app: KoaApp) => new () => T;
@@ -1,16 +1,17 @@
1
1
  import type { FrameworkAugment, KoaApp, KoaAppExtensions, KoaRouter } from "../packages/core/index";
2
- import { GetInstance } from "typings/type";
3
2
  import type { DefaultAppConfig } from "../config/config.default";
4
3
  import type getProjectController from "./controller/project";
5
4
  import type getViewController from "./controller/view";
6
- import type getFetch from "./extend/$fetch";
7
- import type getCrypto from "./extend/crypto";
8
- import type getDB from "./extend/db";
9
- import type generateErrorMessage from "./extend/generateErrorMessage";
10
- import type getLogger from "./extend/logger";
11
- import type parsingParamsOnUrl from "./extend/parsingParamsOnUrl";
12
- import renderView from "./extend/render-view";
5
+ import type getFetch from "./extends/$fetch";
6
+ import type getCrypto from "./extends/crypto";
7
+ import type getDB from "./extends/db";
8
+ import type generateErrorMessage from "./extends/generateErrorMessage";
9
+ import type localCacheHtmlEtag from "./extends/localCacheHtmlEtag";
10
+ import type getLogger from "./extends/logger";
11
+ import type parsingParamsOnUrl from "./extends/parsingParamsOnUrl";
12
+ import type renderView from "./extends/render-view";
13
13
  import type getProjectService from "./service/project";
14
+ import { GetInstance } from "typings/type";
14
15
  type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
15
16
  declare module '../packages/core/index' {
16
17
  namespace FrameworkAugment {
@@ -30,6 +31,7 @@ declare module '../packages/core/index' {
30
31
  $fetch: ReturnType<typeof getFetch>;
31
32
  nunjucksEnv: import('nunjucks').Environment;
32
33
  renderView: ReturnType<typeof renderView>;
34
+ localCacheHtmlEtag: ReturnType<typeof localCacheHtmlEtag>;
33
35
  }
34
36
  interface IMiddlewaresAugmented {
35
37
  errorHandle: import('koa').Middleware;
@@ -11,6 +11,10 @@ export interface BuildFEOptions {
11
11
  * - Maybe you really do not need it.
12
12
  */
13
13
  output?: 'frame' | 'run' | (() => string);
14
+ /**
15
+ * Compress the html content emitted by Vite before writing final `.tpl` / `.html` files.
16
+ */
17
+ minifyHtml?: boolean;
14
18
  }
15
19
  export declare const buildFESharedState: {
16
20
  options: BuildFEOptions;
@@ -1,3 +1,4 @@
1
+ import { Plugin } from "vite";
1
2
  /**
2
3
  *
3
4
  * 寻找 frontend\/**\/*.entry.[j|t]s(x)?
@@ -6,4 +7,8 @@
6
7
  export declare function entries(): Record<string, string>;
7
8
  export declare function outDir(): string;
8
9
  export declare const watchFiles: (callback?: () => Promise<any>) => Promise<void>;
10
+ /**
11
+ * 打包完成后触发
12
+ */
13
+ export declare function generateBuildKeyPlugin(): Plugin;
9
14
  export declare const VBuildFE: (input: Record<string, string>, OperatingEnv?: "dev" | "prod") => Promise<void>;
package/types/index.d.ts CHANGED
@@ -3,8 +3,8 @@ import type Router from "koa-router";
3
3
  import "./app/typings";
4
4
  import { MOmit } from "./typings/type";
5
5
  export type { FrameworkAugment, KoaApp } from "./packages/core/index";
6
- export type { CryptoExtend, CryptoHashAlgorithm, HmacSignOptions, SignedPayloadOptions, VerifySignedPayloadOptions, } from "./app/extend/crypto";
7
- export type { DB, DBDataOptions, DBDataRecord, DBFactory, DBRunResult, FrameworkDB, ListDBDataOptions, SQLiteParams, SQLiteValue, } from "./app/extend/db";
6
+ export type { CryptoExtend, CryptoHashAlgorithm, HmacSignOptions, SignedPayloadOptions, VerifySignedPayloadOptions, } from "./app/extends/crypto";
7
+ export type { DB, DBDataOptions, DBDataRecord, DBFactory, DBRunResult, FrameworkDB, ListDBDataOptions, SQLiteParams, SQLiteValue, } from "./app/extends/db";
8
8
  export type { ControllerFN, Ctx, MiddlewareFN, RouterFN, ServiceFN } from "./app/type";
9
9
  export type { Router };
10
10
  export declare const serverStart: (options?: MOmit<StartOptions, "frameBaseDir">) => Promise<import("./packages/core/index").KoaApp>;
@@ -23,7 +23,7 @@ export declare const baseFn: {
23
23
  new (): {
24
24
  get app(): import("./app/type").KoaApp;
25
25
  get config(): import("./app/type").KoaApp["config"];
26
- get curl(): import("./app/extend/$fetch").NodeFetch;
26
+ get curl(): import("./app/extends/$fetch").NodeFetch;
27
27
  };
28
28
  };
29
29
  };
@@ -1,3 +1,19 @@
1
1
  export declare const isBlank: (value: string | null | undefined) => boolean;
2
2
  export declare const capitalize: (value: string) => string;
3
3
  export declare const kebabCase: (value: string) => string;
4
+ type JoinStrValue = string | number | boolean | null | undefined;
5
+ type JoinStrConditionalValue = readonly [condition: unknown, value: JoinStrValue];
6
+ type JoinStrInput = JoinStrValue | JoinStrConditionalValue;
7
+ type JoinStrOptions = {
8
+ separator?: string;
9
+ };
10
+ type JoinStrArgs = readonly JoinStrInput[] | readonly [...JoinStrInput[], JoinStrOptions];
11
+ /**
12
+ * 拼接字符串片段,自动跳过空值和不满足条件的片段。
13
+ *
14
+ * @example
15
+ * joinStr('btn', isActive && 'active', [disabled, 'disabled'], { separator: ' ' })
16
+ * // => 'btn active disabled'
17
+ */
18
+ export declare const joinStr: (...strings: JoinStrArgs) => string;
19
+ export {};
@@ -2,7 +2,7 @@ import type { KoaApp } from "../types";
2
2
  /**
3
3
  * extend loader 扩展 koa app属性 只加载一级
4
4
  *
5
- * 加载 xx/app/extend 文件,可通过 'app.extends.${文件}' 访问
5
+ * 加载 xx/app/extends 文件,可通过 'app.extends.${文件}' 访问
6
6
  */
7
7
  declare const _default: (app: KoaApp) => Promise<void>;
8
8
  export default _default;
@@ -48,6 +48,10 @@ export interface KoaAppExtensions {
48
48
  * 存着 框架 以及业务方的 app路径
49
49
  */
50
50
  paths: AppPathInfo[];
51
+ /**
52
+ * 静态资源目录列表
53
+ */
54
+ publicsPath: string[];
51
55
  /**
52
56
  * 服务生命周期
53
57
  */
@@ -1 +0,0 @@
1
- const e=require(`../../_virtual/_rolldown/runtime.js`),t=require(`../../packages/core/paths.js`);let n=require(`node:path`);n=e.__toESM(n);let r=require(`nunjucks`);r=e.__toESM(r);var i=e=>{let i=[n.default.resolve(t.getAppPath(e,`frame`),`./public/dist`),n.default.resolve(t.getAppPath(e,`business`),`./public/dist`),...e.options.additionalPublicPaths??[]];console.log(i);let a=r.default.configure(i,{autoescape:!0,throwOnUndefined:!1,trimBlocks:!1,lstripBlocks:!1,noCache:e.envs.get()===`local`,...typeof e.config.nunjucks==`object`?e.config.nunjucks:{}});return e.extends.nunjucksEnv=a,(e,t,n)=>{t.body=a.render(e,Object.assign({},t.state,n))}};module.exports=i;
@@ -1,25 +0,0 @@
1
- import { getAppPath as e } from "../../packages/core/paths.js";
2
- import t from "node:path";
3
- import n from "nunjucks";
4
- //#region app/extend/render-view.ts
5
- var r = (r) => {
6
- let i = [
7
- t.resolve(e(r, "frame"), "./public/dist"),
8
- t.resolve(e(r, "business"), "./public/dist"),
9
- ...r.options.additionalPublicPaths ?? []
10
- ];
11
- console.log(i);
12
- let a = n.configure(i, {
13
- autoescape: !0,
14
- throwOnUndefined: !1,
15
- trimBlocks: !1,
16
- lstripBlocks: !1,
17
- noCache: r.envs.get() === "local",
18
- ...typeof r.config.nunjucks == "object" ? r.config.nunjucks : {}
19
- });
20
- return r.extends.nunjucksEnv = a, (e, t, n) => {
21
- t.body = a.render(e, Object.assign({}, t.state, n));
22
- };
23
- };
24
- //#endregion
25
- export { r as default };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes