shuidi.sharepublic.sdk 0.1.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 (2) hide show
  1. package/package.json +16 -0
  2. package/sharepublicsdk.js +160 -0
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "shuidi.sharepublic.sdk",
3
+ "version": "0.1.0",
4
+ "description": "SDK for initializing shared public components into a container",
5
+ "main": "sharepublicsdk.js",
6
+ "browser": "sharepublicsdk.js",
7
+ "keywords": [
8
+ "sharepublic",
9
+ "components",
10
+ "sdk",
11
+ "iframe"
12
+ ],
13
+ "license": "MIT"
14
+ }
15
+
16
+
@@ -0,0 +1,160 @@
1
+ // SharePublic SDK
2
+ ;(function (global) {
3
+ 'use strict'
4
+
5
+ const BASE_URL = 'http://127.0.0.1:9001'
6
+
7
+ function init(options) {
8
+ const { containerId, componentId, token, props = {}, baseUrl = BASE_URL } = options || {}
9
+
10
+ if (!componentId) throw new Error('缺少 componentId')
11
+
12
+ const container = typeof containerId === 'string'
13
+ ? document.getElementById(containerId)
14
+ : containerId
15
+ if (!container) throw new Error('找不到容器:' + containerId)
16
+
17
+ const url = baseUrl.replace(/\/+$/, '') + '/api/v1/components/' + componentId
18
+
19
+ return fetch(url)
20
+ .then(r => {
21
+ if (!r.ok) throw new Error('获取组件失败')
22
+ return r.json()
23
+ })
24
+ .then(component => {
25
+ if (component.component_type !== 'iframe' || !component.iframe_url) {
26
+ throw new Error('不支持的组件类型')
27
+ }
28
+
29
+ // 将 props 编码成 URL 参数
30
+ const queryParams = []
31
+
32
+ // 处理 props,将对象和数组序列化为 JSON 字符串
33
+ if (props && typeof props === 'object') {
34
+ Object.keys(props).forEach(key => {
35
+ const value = props[key]
36
+ if (value !== undefined && value !== null) {
37
+ // 如果是对象或数组,序列化为 JSON 字符串
38
+ const encodedValue = typeof value === 'object'
39
+ ? encodeURIComponent(JSON.stringify(value))
40
+ : encodeURIComponent(String(value))
41
+ queryParams.push(encodeURIComponent(key) + '=' + encodedValue)
42
+ }
43
+ })
44
+ }
45
+
46
+ // 添加 token
47
+ if (token) {
48
+ queryParams.push('token=' + encodeURIComponent(token))
49
+ }
50
+
51
+ // 构建完整的 iframe URL
52
+ const qs = queryParams.join('&')
53
+ const separator = component.iframe_url.includes('?') ? '&' : '?'
54
+ const src = component.iframe_url + (qs ? separator + qs : '')
55
+
56
+ container.innerHTML = ''
57
+ const iframe = document.createElement('iframe')
58
+ iframe.src = src
59
+ iframe.width = '100%'
60
+ iframe.height = '100%'
61
+ iframe.style.border = 'none'
62
+ iframe.setAttribute('frameborder', '0')
63
+ container.appendChild(iframe)
64
+
65
+ // 创建组件实例对象,提供调用方法的功能
66
+ const componentInstance = {
67
+ iframe: iframe,
68
+ componentId: componentId,
69
+ methods: component.methods || {},
70
+
71
+ /**
72
+ * 调用组件的公共方法
73
+ * @param {string} methodName - 方法名
74
+ * @param {object} params - 方法参数对象
75
+ * @returns {Promise} - 返回 Promise,如果组件有响应则 resolve
76
+ */
77
+ callMethod: function(methodName, params = {}) {
78
+ if (!methodName || typeof methodName !== 'string') {
79
+ return Promise.reject(new Error('方法名必须是字符串'))
80
+ }
81
+
82
+ // 检查方法是否存在
83
+ if (!this.methods[methodName]) {
84
+ return Promise.reject(new Error(`方法 "${methodName}" 不存在`))
85
+ }
86
+
87
+ // 通过 postMessage 向 iframe 发送消息
88
+ const message = {
89
+ type: 'callMethod',
90
+ method: methodName,
91
+ params: params
92
+ }
93
+
94
+ // 发送消息到 iframe
95
+ if (iframe.contentWindow) {
96
+ iframe.contentWindow.postMessage(message, '*')
97
+
98
+ // 返回 Promise,可以用于处理响应(如果组件有响应的话)
99
+ return Promise.resolve({
100
+ method: methodName,
101
+ params: params,
102
+ sent: true
103
+ })
104
+ } else {
105
+ return Promise.reject(new Error('iframe 尚未加载完成'))
106
+ }
107
+ },
108
+
109
+ /**
110
+ * 监听来自组件的消息(事件)
111
+ * @param {string} eventName - 事件名
112
+ * @param {function} callback - 回调函数
113
+ */
114
+ on: function(eventName, callback) {
115
+ if (typeof callback !== 'function') {
116
+ throw new Error('回调函数必须是函数')
117
+ }
118
+
119
+ const messageHandler = (event) => {
120
+ // 验证消息来源(可选,根据实际需求调整)
121
+ if (event.data && event.data.type === 'event' && event.data.event === eventName) {
122
+ callback(event.data.params || {})
123
+ }
124
+ }
125
+
126
+ window.addEventListener('message', messageHandler)
127
+
128
+ // 返回取消监听的函数
129
+ return () => {
130
+ window.removeEventListener('message', messageHandler)
131
+ }
132
+ }
133
+ }
134
+
135
+ // 等待 iframe 加载完成后返回组件实例
136
+ return new Promise((resolve, reject) => {
137
+ iframe.onload = () => {
138
+ resolve(componentInstance)
139
+ }
140
+ iframe.onerror = () => {
141
+ reject(new Error('iframe 加载失败'))
142
+ }
143
+ // 如果 iframe 已经加载完成
144
+ if (iframe.contentDocument && iframe.contentDocument.readyState === 'complete') {
145
+ resolve(componentInstance)
146
+ }
147
+ })
148
+ })
149
+ }
150
+
151
+ const api = { init }
152
+
153
+ if (typeof module !== 'undefined' && module.exports) {
154
+ module.exports = api
155
+ } else if (typeof define === 'function' && define.amd) {
156
+ define([], () => api)
157
+ } else {
158
+ global.SharePublicSDK = api
159
+ }
160
+ })(typeof window !== 'undefined' ? window : this)