mp-taro-kit 0.0.3 → 0.0.4

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 (139) hide show
  1. package/README.md +2 -2
  2. package/dist/core/configure.cjs +75 -0
  3. package/dist/core/configure.d.ts +18 -0
  4. package/dist/core/configure.js +69 -0
  5. package/dist/core/faces.cjs +2 -0
  6. package/dist/core/faces.d.ts +42 -0
  7. package/dist/core/faces.js +1 -0
  8. package/dist/core/index.cjs +30 -0
  9. package/dist/core/index.d.ts +6 -1
  10. package/dist/core/index.js +5 -1
  11. package/dist/core/request.cjs +60 -0
  12. package/dist/core/request.d.ts +27 -0
  13. package/dist/core/request.js +51 -0
  14. package/dist/core/router.cjs +71 -0
  15. package/dist/core/router.d.ts +11 -0
  16. package/dist/core/router.js +63 -0
  17. package/dist/core/storage.cjs +63 -0
  18. package/dist/core/storage.d.ts +6 -0
  19. package/dist/core/storage.js +57 -0
  20. package/dist/core/weapp.cjs +37 -0
  21. package/dist/core/weapp.d.ts +7 -0
  22. package/dist/core/weapp.js +32 -0
  23. package/dist/design/tokens.css +59 -9
  24. package/dist/runtime/index.cjs +13 -0
  25. package/dist/runtime/index.d.ts +5 -1
  26. package/dist/runtime/index.js +6 -1
  27. package/dist/runtime/loading-slot.cjs +44 -0
  28. package/dist/runtime/loading-slot.d.ts +15 -0
  29. package/dist/runtime/loading-slot.js +41 -0
  30. package/dist/runtime/notify.cjs +52 -0
  31. package/dist/runtime/notify.d.ts +19 -0
  32. package/dist/runtime/notify.js +49 -0
  33. package/dist/runtime/overlay-stack.cjs +49 -0
  34. package/dist/runtime/overlay-stack.d.ts +17 -0
  35. package/dist/runtime/overlay-stack.js +46 -0
  36. package/dist/runtime/singleton.cjs +17 -0
  37. package/dist/runtime/singleton.d.ts +6 -0
  38. package/dist/runtime/singleton.js +14 -0
  39. package/dist/runtime/thenable.cjs +17 -0
  40. package/dist/runtime/thenable.d.ts +7 -0
  41. package/dist/runtime/thenable.js +13 -0
  42. package/dist/styles/tokens.css +59 -9
  43. package/dist/ui/actions/Button.cjs +32 -0
  44. package/dist/ui/actions/Button.d.ts +13 -0
  45. package/dist/ui/actions/Button.js +29 -0
  46. package/dist/ui/actions/index.cjs +5 -0
  47. package/dist/ui/actions/index.d.ts +1 -0
  48. package/dist/ui/actions/index.js +1 -0
  49. package/dist/ui/actions/style/index.css +22 -0
  50. package/dist/ui/commands.cjs +86 -0
  51. package/dist/ui/commands.d.ts +21 -0
  52. package/dist/ui/commands.js +73 -0
  53. package/dist/ui/display/Badge.cjs +10 -0
  54. package/dist/ui/display/Badge.d.ts +9 -0
  55. package/dist/ui/display/Badge.js +7 -0
  56. package/dist/ui/display/Divider.cjs +9 -0
  57. package/dist/ui/display/Divider.d.ts +5 -0
  58. package/dist/ui/display/Divider.js +6 -0
  59. package/dist/ui/display/index.cjs +7 -0
  60. package/dist/ui/display/index.d.ts +2 -0
  61. package/dist/ui/display/index.js +2 -0
  62. package/dist/ui/display/style/index.css +30 -0
  63. package/dist/ui/feedback/Dialog.cjs +12 -0
  64. package/dist/ui/feedback/Dialog.d.ts +15 -0
  65. package/dist/ui/feedback/Dialog.js +9 -0
  66. package/dist/ui/feedback/Loading.cjs +12 -0
  67. package/dist/ui/feedback/Loading.d.ts +7 -0
  68. package/dist/ui/feedback/Loading.js +9 -0
  69. package/dist/ui/feedback/Toast.cjs +12 -0
  70. package/dist/ui/feedback/Toast.d.ts +9 -0
  71. package/dist/ui/feedback/Toast.js +9 -0
  72. package/dist/ui/feedback/index.cjs +9 -0
  73. package/dist/ui/feedback/index.d.ts +3 -0
  74. package/dist/ui/feedback/index.js +3 -0
  75. package/dist/ui/feedback/style/index.css +67 -0
  76. package/dist/ui/index.cjs +15 -0
  77. package/dist/ui/index.d.ts +4 -1
  78. package/dist/ui/index.js +2 -1
  79. package/dist/ui/infra/OverlayHost.cjs +33 -0
  80. package/dist/ui/infra/OverlayHost.d.ts +8 -0
  81. package/dist/ui/infra/OverlayHost.js +30 -0
  82. package/dist/ui/infra/SafeArea.cjs +10 -0
  83. package/dist/ui/infra/SafeArea.d.ts +8 -0
  84. package/dist/ui/infra/SafeArea.js +7 -0
  85. package/dist/ui/infra/index.cjs +11 -0
  86. package/dist/ui/infra/index.d.ts +3 -0
  87. package/dist/ui/infra/index.js +3 -0
  88. package/dist/ui/infra/style/index.css +83 -0
  89. package/dist/ui/infra/use-store.cjs +17 -0
  90. package/dist/ui/infra/use-store.d.ts +8 -0
  91. package/dist/ui/infra/use-store.js +12 -0
  92. package/dist/ui/layout/Mask.cjs +12 -0
  93. package/dist/ui/layout/Mask.d.ts +7 -0
  94. package/dist/ui/layout/Mask.js +9 -0
  95. package/dist/ui/layout/Overlay.cjs +11 -0
  96. package/dist/ui/layout/Overlay.d.ts +8 -0
  97. package/dist/ui/layout/Overlay.js +8 -0
  98. package/dist/ui/layout/Popup.cjs +13 -0
  99. package/dist/ui/layout/Popup.d.ts +11 -0
  100. package/dist/ui/layout/Popup.js +10 -0
  101. package/dist/ui/layout/index.cjs +9 -0
  102. package/dist/ui/layout/index.d.ts +3 -0
  103. package/dist/ui/layout/index.js +3 -0
  104. package/dist/ui/layout/style/index.css +51 -0
  105. package/dist/ui/navigation/Drawer.cjs +12 -0
  106. package/dist/ui/navigation/Drawer.d.ts +11 -0
  107. package/dist/ui/navigation/Drawer.js +9 -0
  108. package/dist/ui/navigation/Dropdown.cjs +12 -0
  109. package/dist/ui/navigation/Dropdown.d.ts +9 -0
  110. package/dist/ui/navigation/Dropdown.js +9 -0
  111. package/dist/ui/navigation/index.cjs +7 -0
  112. package/dist/ui/navigation/index.d.ts +2 -0
  113. package/dist/ui/navigation/index.js +2 -0
  114. package/dist/ui/navigation/style/index.css +42 -0
  115. package/dist/ui/state.cjs +20 -0
  116. package/dist/ui/state.d.ts +25 -0
  117. package/dist/ui/state.js +17 -0
  118. package/dist/utils/date.cjs +98 -0
  119. package/dist/utils/date.d.ts +18 -0
  120. package/dist/utils/date.js +89 -0
  121. package/dist/utils/i18n.cjs +31 -0
  122. package/dist/utils/i18n.d.ts +11 -0
  123. package/dist/utils/i18n.js +25 -0
  124. package/dist/utils/index.cjs +28 -0
  125. package/dist/utils/index.d.ts +5 -1
  126. package/dist/utils/index.js +6 -1
  127. package/dist/utils/messages.zh.cjs +13 -0
  128. package/dist/utils/messages.zh.d.ts +1 -0
  129. package/dist/utils/messages.zh.js +10 -0
  130. package/dist/utils/number.cjs +38 -0
  131. package/dist/utils/number.d.ts +6 -0
  132. package/dist/utils/number.js +33 -0
  133. package/dist/utils/path.cjs +33 -0
  134. package/dist/utils/path.d.ts +8 -0
  135. package/dist/utils/path.js +27 -0
  136. package/dist/utils/string.cjs +55 -0
  137. package/dist/utils/string.d.ts +8 -0
  138. package/dist/utils/string.js +50 -0
  139. package/package.json +4 -2
@@ -0,0 +1,57 @@
1
+ import { getConfig, getFaces } from './configure.js';
2
+ function keyOf(key) {
3
+ return `${getConfig().storagePrefix}${key}`;
4
+ }
5
+ /** 平台异常 / 脏数据 / 过期都按「用户在场」兜底;未 configure() 由 getFaces 抛错。 */
6
+ export function storageGet(key) {
7
+ const faces = getFaces();
8
+ try {
9
+ const raw = faces.getStorage(keyOf(key));
10
+ if (raw === undefined || raw === null || raw === '')
11
+ return undefined;
12
+ const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
13
+ if (parsed === null || typeof parsed !== 'object' || !('v' in parsed))
14
+ return undefined;
15
+ const record = parsed;
16
+ if (record.e !== null && record.e !== undefined && record.e <= Date.now()) {
17
+ faces.removeStorage(keyOf(key));
18
+ return undefined;
19
+ }
20
+ return record.v;
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ }
26
+ /** 返回 false 表示平台写入失败,不静默、也不抛。 */
27
+ export function storageSet(key, value, ttlMs) {
28
+ const faces = getFaces();
29
+ const record = { v: value, e: ttlMs === undefined ? null : Date.now() + ttlMs };
30
+ try {
31
+ faces.setStorage(keyOf(key), JSON.stringify(record));
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ export function storageRemove(key) {
39
+ const faces = getFaces();
40
+ try {
41
+ faces.removeStorage(keyOf(key));
42
+ return true;
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }
48
+ export function storageClear() {
49
+ const faces = getFaces();
50
+ try {
51
+ faces.clearStorage();
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.login = login;
4
+ exports.scanCode = scanCode;
5
+ exports.requestPayment = requestPayment;
6
+ const configure_js_1 = require("./configure.cjs");
7
+ /** 微信专有 API 的统一 Promise 化收口;平台失败返回兜底,不抛给页面。 */
8
+ async function login() {
9
+ const faces = (0, configure_js_1.getFaces)();
10
+ try {
11
+ const result = await faces.login();
12
+ return result !== null && result !== undefined && typeof result.code === 'string' ? result : undefined;
13
+ }
14
+ catch {
15
+ return undefined;
16
+ }
17
+ }
18
+ async function scanCode() {
19
+ const faces = (0, configure_js_1.getFaces)();
20
+ try {
21
+ const result = await faces.scanCode();
22
+ return typeof result?.result === 'string' ? result.result : undefined;
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ }
28
+ async function requestPayment(options) {
29
+ const faces = (0, configure_js_1.getFaces)();
30
+ try {
31
+ await faces.requestPayment(options);
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
@@ -0,0 +1,7 @@
1
+ import type { PaymentOptions } from './faces.js';
2
+ /** 微信专有 API 的统一 Promise 化收口;平台失败返回兜底,不抛给页面。 */
3
+ export declare function login(): Promise<{
4
+ code: string;
5
+ } | undefined>;
6
+ export declare function scanCode(): Promise<string | undefined>;
7
+ export declare function requestPayment(options: PaymentOptions): Promise<boolean>;
@@ -0,0 +1,32 @@
1
+ import { getFaces } from './configure.js';
2
+ /** 微信专有 API 的统一 Promise 化收口;平台失败返回兜底,不抛给页面。 */
3
+ export async function login() {
4
+ const faces = getFaces();
5
+ try {
6
+ const result = await faces.login();
7
+ return result !== null && result !== undefined && typeof result.code === 'string' ? result : undefined;
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ export async function scanCode() {
14
+ const faces = getFaces();
15
+ try {
16
+ const result = await faces.scanCode();
17
+ return typeof result?.result === 'string' ? result.result : undefined;
18
+ }
19
+ catch {
20
+ return undefined;
21
+ }
22
+ }
23
+ export async function requestPayment(options) {
24
+ const faces = getFaces();
25
+ try {
26
+ await faces.requestPayment(options);
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
@@ -1,10 +1,60 @@
1
- /* mp-taro-kit 对外样式变量入口。
2
- token 清单与取值待能力清单定稿后补齐;此处只保留覆盖已定五类样式值的最小占位,
3
- 保证 ./styles/tokens 出口有实体、宿主可 import。 */
4
- :root {
5
- --mp-color-primary: #1677ff;
6
- --mp-radius-md: 8px;
7
- --mp-space-md: 12px;
8
- --mp-font-size-md: 14px;
9
- --mp-duration-base: 200ms;
1
+ /* mp-taro-kit 对外样式变量唯一真源。宿主 import 'mp-taro-kit/styles/tokens' 后覆盖同名变量即可整体换肤;
2
+ 组件侧只写 var(--mptk-*),不自带兜底值、不在别处复制数值。命名按 dsh-plugin-core 通用层对齐。
3
+ 边框色沿用其 4% / 10% / 12% 档,写成 rgba 字面量以避开小程序端 8 位 hex 的兼容问题。
4
+ 待实机验证:page 挂载与 px 单位在 Skyline / WebView 双端的实际表现,须宿主 demo 确认。 */
5
+ page {
6
+ /* 文字 */
7
+ --mptk-fg: #1f2328;
8
+ --mptk-fg-2: #5c6370;
9
+ --mptk-fg-3: #767d87;
10
+ --mptk-fg-4: #9aa1ab;
11
+
12
+ /* 面 */
13
+ --mptk-surface-1: #fff;
14
+ --mptk-surface-2: #fff;
15
+ --mptk-surface-3: #fff;
16
+ --mptk-surface-base: #fff;
17
+
18
+ /* 描边 */
19
+ --mptk-border-faint: rgba(0, 0, 0, .04);
20
+ --mptk-border: rgba(0, 0, 0, .10);
21
+ --mptk-border-strong: rgba(0, 0, 0, .12);
22
+
23
+ /* 语义色 */
24
+ --mptk-business: #3b5bdb;
25
+ --mptk-success: #22c55e;
26
+ --mptk-warning: #f59e0b;
27
+ --mptk-danger: #ec1313;
28
+
29
+ /* 圆角 */
30
+ --mptk-radius-xs: 4px;
31
+ --mptk-radius-sm: 8px;
32
+ --mptk-radius-md: 12px;
33
+ --mptk-radius-lg: 16px;
34
+ --mptk-radius-xl: 20px;
35
+ --mptk-radius-pill: 999px;
36
+
37
+ /* 间距(4px 等差) */
38
+ --mptk-space-1: 4px;
39
+ --mptk-space-2: 8px;
40
+ --mptk-space-3: 12px;
41
+ --mptk-space-4: 16px;
42
+
43
+ /* 字号 / 行高成对 */
44
+ --mptk-font-xs: 11px;
45
+ --mptk-font-sm: 12px;
46
+ --mptk-font-md: 13px;
47
+ --mptk-font-lg: 14px;
48
+ --mptk-font-xl: 16px;
49
+ --mptk-line-xs: 14px;
50
+ --mptk-line-sm: 18px;
51
+ --mptk-line-md: 20px;
52
+ --mptk-line-lg: 22px;
53
+ --mptk-line-xl: 24px;
54
+
55
+ /* 动画 */
56
+ --mptk-dur: .2s;
57
+ --mptk-dur-fast: .12s;
58
+ --mptk-dur-run: 500ms;
59
+ --mptk-ease: cubic-bezier(.4, 0, .2, 1);
10
60
  }
@@ -1,2 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLoadingSlot = exports.createNotifyCenter = exports.createOverlayStack = exports.createSingleton = exports.isSuccess = exports.isThenable = void 0;
4
+ // runtime 层单点出口:只做具名 re-export,不含实现。
5
+ var thenable_js_1 = require("./thenable.cjs");
6
+ Object.defineProperty(exports, "isThenable", { enumerable: true, get: function () { return thenable_js_1.isThenable; } });
7
+ Object.defineProperty(exports, "isSuccess", { enumerable: true, get: function () { return thenable_js_1.isSuccess; } });
8
+ var singleton_js_1 = require("./singleton.cjs");
9
+ Object.defineProperty(exports, "createSingleton", { enumerable: true, get: function () { return singleton_js_1.createSingleton; } });
10
+ var overlay_stack_js_1 = require("./overlay-stack.cjs");
11
+ Object.defineProperty(exports, "createOverlayStack", { enumerable: true, get: function () { return overlay_stack_js_1.createOverlayStack; } });
12
+ var notify_js_1 = require("./notify.cjs");
13
+ Object.defineProperty(exports, "createNotifyCenter", { enumerable: true, get: function () { return notify_js_1.createNotifyCenter; } });
14
+ var loading_slot_js_1 = require("./loading-slot.cjs");
15
+ Object.defineProperty(exports, "createLoadingSlot", { enumerable: true, get: function () { return loading_slot_js_1.createLoadingSlot; } });
@@ -1 +1,5 @@
1
- export {};
1
+ export { isThenable, isSuccess } from './thenable.js';
2
+ export { createSingleton } from './singleton.js';
3
+ export { createOverlayStack, type OverlayEntry, type OverlayStack, } from './overlay-stack.js';
4
+ export { createNotifyCenter, type Notice, type NoticeTone, type NotifyCenter, } from './notify.js';
5
+ export { createLoadingSlot, type LoadingState, type LoadingSlot, } from './loading-slot.js';
@@ -1 +1,6 @@
1
- export {};
1
+ // runtime 层单点出口:只做具名 re-export,不含实现。
2
+ export { isThenable, isSuccess } from './thenable.js';
3
+ export { createSingleton } from './singleton.js';
4
+ export { createOverlayStack, } from './overlay-stack.js';
5
+ export { createNotifyCenter, } from './notify.js';
6
+ export { createLoadingSlot, } from './loading-slot.js';
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLoadingSlot = createLoadingSlot;
4
+ /**
5
+ * 全局唯一 loading 槽:句柄 id 配对,重复 hide / 未知 id 返回 false 且不误关别人的。
6
+ * 计数归零才 inactive;状态真变了才通知,getSnapshot 引用稳定。
7
+ */
8
+ function createLoadingSlot() {
9
+ const handles = new Set();
10
+ let seq = 0;
11
+ let snapshot = { active: false, count: 0 };
12
+ const listeners = new Set();
13
+ const refresh = () => {
14
+ const next = { active: handles.size > 0, count: handles.size };
15
+ if (next.active === snapshot.active && next.count === snapshot.count)
16
+ return;
17
+ snapshot = next;
18
+ for (const listener of listeners)
19
+ listener();
20
+ };
21
+ return {
22
+ show() {
23
+ const id = ++seq;
24
+ handles.add(id);
25
+ refresh();
26
+ return id;
27
+ },
28
+ hide(id) {
29
+ const removed = handles.delete(id);
30
+ if (removed)
31
+ refresh();
32
+ return removed;
33
+ },
34
+ getSnapshot() {
35
+ return snapshot;
36
+ },
37
+ subscribe(listener) {
38
+ listeners.add(listener);
39
+ return () => {
40
+ listeners.delete(listener);
41
+ };
42
+ },
43
+ };
44
+ }
@@ -0,0 +1,15 @@
1
+ export interface LoadingState {
2
+ readonly active: boolean;
3
+ readonly count: number;
4
+ }
5
+ export interface LoadingSlot {
6
+ show(): number;
7
+ hide(id: number): boolean;
8
+ getSnapshot(): LoadingState;
9
+ subscribe(listener: () => void): () => void;
10
+ }
11
+ /**
12
+ * 全局唯一 loading 槽:句柄 id 配对,重复 hide / 未知 id 返回 false 且不误关别人的。
13
+ * 计数归零才 inactive;状态真变了才通知,getSnapshot 引用稳定。
14
+ */
15
+ export declare function createLoadingSlot(): LoadingSlot;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 全局唯一 loading 槽:句柄 id 配对,重复 hide / 未知 id 返回 false 且不误关别人的。
3
+ * 计数归零才 inactive;状态真变了才通知,getSnapshot 引用稳定。
4
+ */
5
+ export function createLoadingSlot() {
6
+ const handles = new Set();
7
+ let seq = 0;
8
+ let snapshot = { active: false, count: 0 };
9
+ const listeners = new Set();
10
+ const refresh = () => {
11
+ const next = { active: handles.size > 0, count: handles.size };
12
+ if (next.active === snapshot.active && next.count === snapshot.count)
13
+ return;
14
+ snapshot = next;
15
+ for (const listener of listeners)
16
+ listener();
17
+ };
18
+ return {
19
+ show() {
20
+ const id = ++seq;
21
+ handles.add(id);
22
+ refresh();
23
+ return id;
24
+ },
25
+ hide(id) {
26
+ const removed = handles.delete(id);
27
+ if (removed)
28
+ refresh();
29
+ return removed;
30
+ },
31
+ getSnapshot() {
32
+ return snapshot;
33
+ },
34
+ subscribe(listener) {
35
+ listeners.add(listener);
36
+ return () => {
37
+ listeners.delete(listener);
38
+ };
39
+ },
40
+ };
41
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNotifyCenter = createNotifyCenter;
4
+ /**
5
+ * 通知队列:core 与 ui 共用同一份。超出 limit 挤掉最旧一条,
6
+ * 自动消失 / 动画交给 ui 层,本层不碰平台定时器。
7
+ */
8
+ function createNotifyCenter(limit = 3) {
9
+ let notices = [];
10
+ let seq = 0;
11
+ const listeners = new Set();
12
+ const max = Number.isFinite(limit) && limit > 0 ? Math.floor(limit) : 3;
13
+ const notify = () => {
14
+ for (const listener of listeners)
15
+ listener();
16
+ };
17
+ return {
18
+ show(text, tone = 'info') {
19
+ const id = ++seq;
20
+ notices = [...notices, { id, text, tone }];
21
+ if (notices.length > max)
22
+ notices = notices.slice(notices.length - max);
23
+ notify();
24
+ return id;
25
+ },
26
+ dismiss(id) {
27
+ const exists = notices.some((notice) => notice.id === id);
28
+ if (!exists)
29
+ return false;
30
+ notices = notices.filter((notice) => notice.id !== id);
31
+ notify();
32
+ return true;
33
+ },
34
+ clear() {
35
+ if (notices.length === 0)
36
+ return [];
37
+ const removed = notices;
38
+ notices = [];
39
+ notify();
40
+ return removed;
41
+ },
42
+ getSnapshot() {
43
+ return notices;
44
+ },
45
+ subscribe(listener) {
46
+ listeners.add(listener);
47
+ return () => {
48
+ listeners.delete(listener);
49
+ };
50
+ },
51
+ };
52
+ }
@@ -0,0 +1,19 @@
1
+ export type NoticeTone = 'info' | 'success' | 'warn' | 'error';
2
+ /** 文案由调用方传已翻译好的字符串;runtime 不做 i18n,也不做定时消失。 */
3
+ export interface Notice {
4
+ readonly id: number;
5
+ readonly text: string;
6
+ readonly tone: NoticeTone;
7
+ }
8
+ export interface NotifyCenter {
9
+ show(text: string, tone?: NoticeTone): number;
10
+ dismiss(id: number): boolean;
11
+ clear(): Notice[];
12
+ getSnapshot(): readonly Notice[];
13
+ subscribe(listener: () => void): () => void;
14
+ }
15
+ /**
16
+ * 通知队列:core 与 ui 共用同一份。超出 limit 挤掉最旧一条,
17
+ * 自动消失 / 动画交给 ui 层,本层不碰平台定时器。
18
+ */
19
+ export declare function createNotifyCenter(limit?: number): NotifyCenter;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 通知队列:core 与 ui 共用同一份。超出 limit 挤掉最旧一条,
3
+ * 自动消失 / 动画交给 ui 层,本层不碰平台定时器。
4
+ */
5
+ export function createNotifyCenter(limit = 3) {
6
+ let notices = [];
7
+ let seq = 0;
8
+ const listeners = new Set();
9
+ const max = Number.isFinite(limit) && limit > 0 ? Math.floor(limit) : 3;
10
+ const notify = () => {
11
+ for (const listener of listeners)
12
+ listener();
13
+ };
14
+ return {
15
+ show(text, tone = 'info') {
16
+ const id = ++seq;
17
+ notices = [...notices, { id, text, tone }];
18
+ if (notices.length > max)
19
+ notices = notices.slice(notices.length - max);
20
+ notify();
21
+ return id;
22
+ },
23
+ dismiss(id) {
24
+ const exists = notices.some((notice) => notice.id === id);
25
+ if (!exists)
26
+ return false;
27
+ notices = notices.filter((notice) => notice.id !== id);
28
+ notify();
29
+ return true;
30
+ },
31
+ clear() {
32
+ if (notices.length === 0)
33
+ return [];
34
+ const removed = notices;
35
+ notices = [];
36
+ notify();
37
+ return removed;
38
+ },
39
+ getSnapshot() {
40
+ return notices;
41
+ },
42
+ subscribe(listener) {
43
+ listeners.add(listener);
44
+ return () => {
45
+ listeners.delete(listener);
46
+ };
47
+ },
48
+ };
49
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOverlayStack = createOverlayStack;
4
+ /**
5
+ * 栈用不可变替换维护:getSnapshot 返回稳定引用,可直接喂给 useSyncExternalStore。
6
+ * 只有状态真变了才通知订阅者;无效 id / 空栈 clear 返回兜底值且不抛。
7
+ */
8
+ function createOverlayStack() {
9
+ let entries = [];
10
+ let seq = 0;
11
+ const listeners = new Set();
12
+ const notify = () => {
13
+ for (const listener of listeners)
14
+ listener();
15
+ };
16
+ return {
17
+ push(payload) {
18
+ const id = ++seq;
19
+ entries = [...entries, { id, payload }];
20
+ notify();
21
+ return id;
22
+ },
23
+ dismiss(id) {
24
+ const found = entries.find((entry) => entry.id === id);
25
+ if (found === undefined)
26
+ return undefined;
27
+ entries = entries.filter((entry) => entry.id !== id);
28
+ notify();
29
+ return found.payload;
30
+ },
31
+ clear() {
32
+ if (entries.length === 0)
33
+ return [];
34
+ const payloads = entries.map((entry) => entry.payload);
35
+ entries = [];
36
+ notify();
37
+ return payloads;
38
+ },
39
+ getSnapshot() {
40
+ return entries;
41
+ },
42
+ subscribe(listener) {
43
+ listeners.add(listener);
44
+ return () => {
45
+ listeners.delete(listener);
46
+ };
47
+ },
48
+ };
49
+ }
@@ -0,0 +1,17 @@
1
+ /** 浮层条目。栈只存 payload,不掺 resolve / 渲染器,那是 ui 层的事。 */
2
+ export interface OverlayEntry<T> {
3
+ readonly id: number;
4
+ readonly payload: T;
5
+ }
6
+ export interface OverlayStack<T> {
7
+ push(payload: T): number;
8
+ dismiss(id: number): T | undefined;
9
+ clear(): T[];
10
+ getSnapshot(): readonly OverlayEntry<T>[];
11
+ subscribe(listener: () => void): () => void;
12
+ }
13
+ /**
14
+ * 栈用不可变替换维护:getSnapshot 返回稳定引用,可直接喂给 useSyncExternalStore。
15
+ * 只有状态真变了才通知订阅者;无效 id / 空栈 clear 返回兜底值且不抛。
16
+ */
17
+ export declare function createOverlayStack<T>(): OverlayStack<T>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 栈用不可变替换维护:getSnapshot 返回稳定引用,可直接喂给 useSyncExternalStore。
3
+ * 只有状态真变了才通知订阅者;无效 id / 空栈 clear 返回兜底值且不抛。
4
+ */
5
+ export function createOverlayStack() {
6
+ let entries = [];
7
+ let seq = 0;
8
+ const listeners = new Set();
9
+ const notify = () => {
10
+ for (const listener of listeners)
11
+ listener();
12
+ };
13
+ return {
14
+ push(payload) {
15
+ const id = ++seq;
16
+ entries = [...entries, { id, payload }];
17
+ notify();
18
+ return id;
19
+ },
20
+ dismiss(id) {
21
+ const found = entries.find((entry) => entry.id === id);
22
+ if (found === undefined)
23
+ return undefined;
24
+ entries = entries.filter((entry) => entry.id !== id);
25
+ notify();
26
+ return found.payload;
27
+ },
28
+ clear() {
29
+ if (entries.length === 0)
30
+ return [];
31
+ const payloads = entries.map((entry) => entry.payload);
32
+ entries = [];
33
+ notify();
34
+ return payloads;
35
+ },
36
+ getSnapshot() {
37
+ return entries;
38
+ },
39
+ subscribe(listener) {
40
+ listeners.add(listener);
41
+ return () => {
42
+ listeners.delete(listener);
43
+ };
44
+ },
45
+ };
46
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSingleton = createSingleton;
4
+ /**
5
+ * 跨副本单例:Symbol.for 挂在当前 JS 运行时的 globalThis 上,懒建、已存在直接返回。
6
+ * 解决的是「同一进程里库被打进两份」,不是持久化——冷启动后重新建一遍。
7
+ * key 统一带 mptk/ 前缀,避免与其他库撞符号。
8
+ */
9
+ function createSingleton(key, create) {
10
+ const symbol = Symbol.for(`mptk/${key}`);
11
+ const registry = globalThis;
12
+ if (Reflect.has(registry, symbol))
13
+ return registry[symbol];
14
+ const created = create();
15
+ registry[symbol] = created;
16
+ return created;
17
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 跨副本单例:Symbol.for 挂在当前 JS 运行时的 globalThis 上,懒建、已存在直接返回。
3
+ * 解决的是「同一进程里库被打进两份」,不是持久化——冷启动后重新建一遍。
4
+ * key 统一带 mptk/ 前缀,避免与其他库撞符号。
5
+ */
6
+ export declare function createSingleton<T>(key: string, create: () => T): T;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 跨副本单例:Symbol.for 挂在当前 JS 运行时的 globalThis 上,懒建、已存在直接返回。
3
+ * 解决的是「同一进程里库被打进两份」,不是持久化——冷启动后重新建一遍。
4
+ * key 统一带 mptk/ 前缀,避免与其他库撞符号。
5
+ */
6
+ export function createSingleton(key, create) {
7
+ const symbol = Symbol.for(`mptk/${key}`);
8
+ const registry = globalThis;
9
+ if (Reflect.has(registry, symbol))
10
+ return registry[symbol];
11
+ const created = create();
12
+ registry[symbol] = created;
13
+ return created;
14
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isThenable = isThenable;
4
+ exports.isSuccess = isSuccess;
5
+ /** Promise 化交互的判定器:只判定,不 await、不吞错、不改原值。 */
6
+ function isThenable(value) {
7
+ if (value === null || value === undefined)
8
+ return false;
9
+ return typeof value.then === 'function';
10
+ }
11
+ /**
12
+ * 回调的返回值算不算「这次成了」:仅显式 false 表示没成(弹窗据此保持不关、让人重试)。
13
+ * true / undefined / 其他值一律算成,消费方不必在调用点包 try/catch。
14
+ */
15
+ function isSuccess(value) {
16
+ return value !== false;
17
+ }
@@ -0,0 +1,7 @@
1
+ /** Promise 化交互的判定器:只判定,不 await、不吞错、不改原值。 */
2
+ export declare function isThenable(value: unknown): value is PromiseLike<unknown>;
3
+ /**
4
+ * 回调的返回值算不算「这次成了」:仅显式 false 表示没成(弹窗据此保持不关、让人重试)。
5
+ * true / undefined / 其他值一律算成,消费方不必在调用点包 try/catch。
6
+ */
7
+ export declare function isSuccess(value: unknown): boolean;
@@ -0,0 +1,13 @@
1
+ /** Promise 化交互的判定器:只判定,不 await、不吞错、不改原值。 */
2
+ export function isThenable(value) {
3
+ if (value === null || value === undefined)
4
+ return false;
5
+ return typeof value.then === 'function';
6
+ }
7
+ /**
8
+ * 回调的返回值算不算「这次成了」:仅显式 false 表示没成(弹窗据此保持不关、让人重试)。
9
+ * true / undefined / 其他值一律算成,消费方不必在调用点包 try/catch。
10
+ */
11
+ export function isSuccess(value) {
12
+ return value !== false;
13
+ }