e10-ebuilder-prototype 0.5.0

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 (54) hide show
  1. package/README.md +113 -0
  2. package/dist/api.d.ts +12 -0
  3. package/dist/api.js +125 -0
  4. package/dist/application.d.ts +7 -0
  5. package/dist/application.js +16 -0
  6. package/dist/archive.d.ts +130 -0
  7. package/dist/archive.js +151 -0
  8. package/dist/capture.d.ts +15 -0
  9. package/dist/capture.js +440 -0
  10. package/dist/common.d.ts +20 -0
  11. package/dist/common.js +87 -0
  12. package/dist/dom.d.mts +1 -0
  13. package/dist/dom.mjs +58 -0
  14. package/dist/form-context.d.ts +3 -0
  15. package/dist/form-context.js +58 -0
  16. package/dist/form-runtime.d.mts +2 -0
  17. package/dist/form-runtime.mjs +149 -0
  18. package/dist/forms.d.ts +51 -0
  19. package/dist/forms.js +603 -0
  20. package/dist/html.d.ts +22 -0
  21. package/dist/html.js +427 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.js +370 -0
  24. package/dist/menus.d.ts +32 -0
  25. package/dist/menus.js +330 -0
  26. package/dist/model.d.ts +164 -0
  27. package/dist/model.js +8 -0
  28. package/dist/offline-store.d.mts +5 -0
  29. package/dist/offline-store.mjs +80 -0
  30. package/dist/platform.d.ts +10 -0
  31. package/dist/platform.js +123 -0
  32. package/dist/readiness.d.ts +124 -0
  33. package/dist/readiness.js +529 -0
  34. package/dist/runtime-support.d.mts +52 -0
  35. package/dist/runtime-support.mjs +279 -0
  36. package/dist/site.d.ts +34 -0
  37. package/dist/site.js +195 -0
  38. package/dist/store.d.ts +90 -0
  39. package/dist/store.js +296 -0
  40. package/dist/templates/form-guide.md +539 -0
  41. package/dist/templates/index.html +803 -0
  42. package/dist/templates/placeholder.html +143 -0
  43. package/dist/templates/workflow-guide.md +95 -0
  44. package/dist/templates/workflow-presets.json +89 -0
  45. package/dist/temporary-records.d.ts +15 -0
  46. package/dist/temporary-records.js +286 -0
  47. package/dist/vendor/environment-auth.d.ts +61 -0
  48. package/dist/vendor/environment-auth.js +455 -0
  49. package/dist/workflow-runtime.d.mts +2 -0
  50. package/dist/workflow-runtime.mjs +298 -0
  51. package/dist/workflows.d.ts +28 -0
  52. package/dist/workflows.js +90 -0
  53. package/docs/PROTOCOL.md +299 -0
  54. package/package.json +45 -0
@@ -0,0 +1,149 @@
1
+ import { createOfflineStorage } from './offline-store.mjs';
2
+ // Fixed offline transport. Generated business code only uses E10FormStore.
3
+ function installFormStore(scope, objectIds, createStorage) {
4
+ const appId = scope.split(':')[0];
5
+ const allowed = new Set([scope, ...objectIds.map((id) => appId + ':' + id)]);
6
+ const storage = createStorage(appId);
7
+ const valid = storage.valid;
8
+ const local = storage.operate;
9
+ const navigate = (menuKey, params = {}) => {
10
+ if (!/^\d+(?:-\d+)*$/.test(menuKey) ||
11
+ !params ||
12
+ typeof params !== 'object' ||
13
+ Array.isArray(params) ||
14
+ JSON.stringify(params).length > 10000)
15
+ return Promise.reject(new Error('本地跳转参数无效'));
16
+ if (parent === window)
17
+ return Promise.resolve(false);
18
+ return new Promise((resolve) => {
19
+ const requestId = Math.random().toString(36).slice(2);
20
+ let timer;
21
+ const receive = (event) => {
22
+ if (event.source === parent &&
23
+ event.data?.type === 'e10-form-navigation-result' &&
24
+ event.data.requestId === requestId) {
25
+ clearTimeout(timer);
26
+ removeEventListener('message', receive);
27
+ resolve(event.data.ok === true);
28
+ }
29
+ };
30
+ timer = setTimeout(() => {
31
+ removeEventListener('message', receive);
32
+ resolve(false);
33
+ }, 1000);
34
+ addEventListener('message', receive);
35
+ parent.postMessage({ type: 'e10-form-navigation', requestId, menuKey, params }, '*');
36
+ });
37
+ };
38
+ const request = (targetScope, operation, value) => {
39
+ if (!allowed.has(targetScope))
40
+ return Promise.reject(new Error('表单不在当前应用的已发布范围'));
41
+ if (!valid(value) || JSON.stringify(value).length > 2_000_000)
42
+ return Promise.reject(new Error('本地数据格式无效或超过容量'));
43
+ if (parent === window)
44
+ return Promise.resolve(local(targetScope, operation, value));
45
+ return new Promise((resolve, reject) => {
46
+ const requestId = Math.random().toString(36).slice(2) + Date.now().toString(36);
47
+ const finish = () => {
48
+ clearTimeout(timer);
49
+ removeEventListener('message', receive);
50
+ };
51
+ const receive = (event) => {
52
+ if (event.source !== parent ||
53
+ event.data?.type !== 'e10-form-store-result' ||
54
+ event.data.requestId !== requestId)
55
+ return;
56
+ finish();
57
+ if (event.data.error)
58
+ reject(new Error(event.data.error));
59
+ else if (valid(event.data.value))
60
+ resolve(local(targetScope, 'save', event.data.value));
61
+ else
62
+ reject(new Error('主框架返回的数据格式无效'));
63
+ };
64
+ const timer = setTimeout(() => {
65
+ finish();
66
+ resolve(local(targetScope, operation, value));
67
+ }, 1000);
68
+ addEventListener('message', receive);
69
+ parent.postMessage({ type: 'e10-form-store', requestId, operation, scope: targetScope, value }, '*');
70
+ });
71
+ };
72
+ const commit = (changes) => {
73
+ if (!Array.isArray(changes))
74
+ return Promise.reject(new Error('联合保存参数无效'));
75
+ const entries = changes.map(({ objId, value }) => ({ scope: appId + ':' + objId, value }));
76
+ if (!entries.length ||
77
+ entries.length > 100 ||
78
+ new Set(entries.map((e) => e.scope)).size !== entries.length ||
79
+ entries.some((e) => !allowed.has(e.scope) || !valid(e.value)) ||
80
+ JSON.stringify(entries).length > 2_000_000)
81
+ return Promise.reject(new Error('联合保存范围或数据无效'));
82
+ if (parent === window)
83
+ return Promise.resolve(storage.commit(entries));
84
+ return new Promise((resolve, reject) => {
85
+ const requestId = Math.random().toString(36).slice(2) + Date.now().toString(36);
86
+ const finish = () => {
87
+ clearTimeout(timer);
88
+ removeEventListener('message', receive);
89
+ };
90
+ const receive = (event) => {
91
+ if (event.source !== parent ||
92
+ event.data?.type !== 'e10-form-commit-result' ||
93
+ event.data.requestId !== requestId)
94
+ return;
95
+ finish();
96
+ if (event.data.error)
97
+ reject(new Error(event.data.error));
98
+ else
99
+ resolve(event.data.value);
100
+ };
101
+ const timer = setTimeout(() => {
102
+ finish();
103
+ try {
104
+ resolve(storage.commit(entries));
105
+ }
106
+ catch (error) {
107
+ reject(error);
108
+ }
109
+ }, 1000);
110
+ addEventListener('message', receive);
111
+ parent.postMessage({ type: 'e10-form-commit', requestId, entries }, '*');
112
+ });
113
+ };
114
+ const objectStore = (targetScope) => Object.freeze({
115
+ load: (initial) => request(targetScope, 'load', initial),
116
+ save: (state) => request(targetScope, 'save', state),
117
+ reset: (initial) => request(targetScope, 'reset', initial),
118
+ });
119
+ Object.defineProperty(window, 'E10FormStore', {
120
+ value: Object.freeze({
121
+ ...objectStore(scope),
122
+ forObject: (objId) => {
123
+ const targetScope = appId + ':' + objId;
124
+ if (!allowed.has(targetScope))
125
+ throw new Error('表单不在当前应用的已发布范围');
126
+ return objectStore(targetScope);
127
+ },
128
+ commit,
129
+ navigate,
130
+ parameters: () => {
131
+ try {
132
+ const v = JSON.parse(new URLSearchParams(location.hash.slice(1)).get('params') || '{}');
133
+ return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
134
+ }
135
+ catch {
136
+ return {};
137
+ }
138
+ },
139
+ }),
140
+ configurable: true,
141
+ });
142
+ }
143
+ export function formRuntime(scope, objectIds = []) {
144
+ return `<script id="e10-form-runtime">(${installFormStore.toString()})(${JSON.stringify(scope)},${JSON.stringify(objectIds)},${createOfflineStorage.toString()});</script>`;
145
+ }
146
+ export function attachFormRuntime(source, scope, objectIds = []) {
147
+ const clean = source.replace(/<script\b[^>]*\bid\s*=\s*["']e10-form-runtime["'][^>]*>[\s\S]*?<\/script\s*>/gi, '');
148
+ return clean.replace(/<head(?:\s[^>]*)?>/i, (match) => match + formRuntime(scope, objectIds));
149
+ }
@@ -0,0 +1,51 @@
1
+ import type { E10AuthContext } from './vendor/environment-auth.js';
2
+ import type { FormCollection, FormPage, TaskState } from './model.js';
3
+ import type { Store } from './store.js';
4
+ export interface FormInput {
5
+ schema: 1;
6
+ appId: string;
7
+ objId: string;
8
+ name: string;
9
+ page: FormPage;
10
+ fields: any[];
11
+ list?: Record<string, any>;
12
+ buttons: Record<string, any>;
13
+ formButtons: Record<string, any>;
14
+ layout: {
15
+ source: 'html-reference' | 'fields';
16
+ html?: string;
17
+ reason?: string;
18
+ };
19
+ warnings: string[];
20
+ }
21
+ export declare const formInputPath: (store: Store, key: string) => string;
22
+ export declare function formResult(store: Store, key: string): Promise<FormCollection | undefined>;
23
+ export declare function verifiedForm(store: Store, result: FormCollection | undefined): Promise<boolean>;
24
+ export declare function configObject(value: any): Record<string, any>;
25
+ export declare function normalizeFields(groups: any, objId: string): any[];
26
+ export declare function nlistPage(data: any): {
27
+ page: any;
28
+ config: Record<string, any>;
29
+ objId: string;
30
+ listId: string;
31
+ };
32
+ export declare function normalizeButtons(raw: any, scope: Record<string, string>, family: 'list' | 'nlist' | 'layout'): {
33
+ status: string;
34
+ scope: Record<string, string>;
35
+ scopeKey: string;
36
+ sourceFamily: "list" | "nlist" | "layout";
37
+ items: {
38
+ id: string;
39
+ key: any;
40
+ name: any;
41
+ positions: any[];
42
+ enabled: boolean;
43
+ hidden: boolean;
44
+ order: any;
45
+ sourcePath: string;
46
+ buttonRef: string;
47
+ config: any;
48
+ }[];
49
+ raw: any;
50
+ };
51
+ export declare function collectForms(store: Store, state: TaskState, auth: E10AuthContext, retryFailed?: boolean): Promise<void>;