@lingxia/page-runtime 0.5.0 → 0.6.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/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -1
  3. package/dist/shared/runtime.d.ts +1 -12
  4. package/dist/shared/runtime.js +72 -43
  5. package/package.json +6 -32
  6. package/dist/react/LxInput.d.ts +0 -47
  7. package/dist/react/LxInput.js +0 -128
  8. package/dist/react/LxNavigator.d.ts +0 -23
  9. package/dist/react/LxNavigator.js +0 -61
  10. package/dist/react/LxPicker.d.ts +0 -27
  11. package/dist/react/LxPicker.js +0 -113
  12. package/dist/react/LxTextarea.d.ts +0 -47
  13. package/dist/react/LxTextarea.js +0 -118
  14. package/dist/react/LxVideo.d.ts +0 -5
  15. package/dist/react/LxVideo.js +0 -113
  16. package/dist/react/hook.d.ts +0 -39
  17. package/dist/react/hook.js +0 -212
  18. package/dist/react/index.d.ts +0 -6
  19. package/dist/react/index.js +0 -6
  20. package/dist/react/text_component_shared.d.ts +0 -5
  21. package/dist/react/text_component_shared.js +0 -33
  22. package/dist/vue/LxInput.vue +0 -92
  23. package/dist/vue/LxNavigator.vue +0 -79
  24. package/dist/vue/LxPicker.vue +0 -144
  25. package/dist/vue/LxTextarea.vue +0 -90
  26. package/dist/vue/LxVideo.vue +0 -111
  27. package/dist/vue/hook.d.ts +0 -42
  28. package/dist/vue/hook.js +0 -194
  29. package/dist/vue/index.d.ts +0 -7
  30. package/dist/vue/index.js +0 -6
  31. package/dist/vue/text_component_shared.d.ts +0 -3
  32. package/dist/vue/text_component_shared.js +0 -26
  33. package/dist/vue/types.d.ts +0 -101
  34. package/dist/vue/types.js +0 -1
  35. package/src/index.ts +0 -21
  36. package/src/react/LxInput.tsx +0 -224
  37. package/src/react/LxNavigator.tsx +0 -132
  38. package/src/react/LxPicker.tsx +0 -205
  39. package/src/react/LxTextarea.tsx +0 -216
  40. package/src/react/LxVideo.tsx +0 -166
  41. package/src/react/hook.ts +0 -317
  42. package/src/react/index.ts +0 -14
  43. package/src/react/text_component_shared.ts +0 -43
  44. package/src/shared/runtime.ts +0 -186
  45. package/src/vue/LxInput.vue +0 -92
  46. package/src/vue/LxNavigator.vue +0 -79
  47. package/src/vue/LxPicker.vue +0 -144
  48. package/src/vue/LxTextarea.vue +0 -90
  49. package/src/vue/LxVideo.vue +0 -111
  50. package/src/vue/hook.ts +0 -313
  51. package/src/vue/index.ts +0 -22
  52. package/src/vue/shims-vue.d.ts +0 -5
  53. package/src/vue/text_component_shared.ts +0 -33
  54. package/src/vue/types.ts +0 -107
@@ -1,111 +0,0 @@
1
- <script setup lang="ts">
2
- import { ref, computed, h, onBeforeUnmount, useAttrs, useId, watch } from 'vue';
3
- import { registerVideoComponent } from '@lingxia/elements';
4
- import {
5
- buildVideoNativeAttrs,
6
- VIDEO_DOM_EVENT_MAP,
7
- } from '@lingxia/elements';
8
- import { bindElementEvents, unbindElementEvents } from './text_component_shared.js';
9
- import type { LxVideoProps } from './types.js';
10
-
11
- const props = withDefaults(defineProps<LxVideoProps>(), {
12
- autoplay: false,
13
- loop: false,
14
- muted: false,
15
- controls: true,
16
- progressBar: true,
17
- live: false,
18
- });
19
- const attrs = useAttrs();
20
-
21
- const emit = defineEmits<{
22
- playRequest: [e: Event];
23
- play: [e: Event];
24
- playing: [e: Event];
25
- pause: [e: Event];
26
- stop: [e: Event];
27
- ended: [e: Event];
28
- timeUpdate: [e: Event];
29
- error: [e: Event];
30
- loadedMetadata: [e: Event];
31
- fullscreenChange: [e: Event];
32
- waiting: [e: Event];
33
- qualityChange: [e: Event];
34
- rateChange: [e: Event];
35
- }>();
36
-
37
- if (typeof window !== 'undefined') {
38
- registerVideoComponent();
39
- }
40
-
41
- const elementRef = ref<HTMLElement | null>(null);
42
- const vueId = useId();
43
- let boundElement: HTMLElement | null = null;
44
-
45
- const resolvedId = computed(() => props.id || `lx-video-${vueId.replace(/[:]/g, '')}`);
46
-
47
- const videoEventListeners: Record<string, EventListenerObject> = {
48
- [VIDEO_DOM_EVENT_MAP.onPlayRequest]: { handleEvent: (event: Event) => emit('playRequest', event) },
49
- [VIDEO_DOM_EVENT_MAP.onPlay]: { handleEvent: (event: Event) => emit('play', event) },
50
- [VIDEO_DOM_EVENT_MAP.onPlaying]: { handleEvent: (event: Event) => emit('playing', event) },
51
- [VIDEO_DOM_EVENT_MAP.onPause]: { handleEvent: (event: Event) => emit('pause', event) },
52
- [VIDEO_DOM_EVENT_MAP.onStop]: { handleEvent: (event: Event) => emit('stop', event) },
53
- [VIDEO_DOM_EVENT_MAP.onEnded]: { handleEvent: (event: Event) => emit('ended', event) },
54
- [VIDEO_DOM_EVENT_MAP.onTimeUpdate]: { handleEvent: (event: Event) => emit('timeUpdate', event) },
55
- [VIDEO_DOM_EVENT_MAP.onError]: { handleEvent: (event: Event) => emit('error', event) },
56
- [VIDEO_DOM_EVENT_MAP.onLoadedMetadata]: { handleEvent: (event: Event) => emit('loadedMetadata', event) },
57
- [VIDEO_DOM_EVENT_MAP.onFullscreenChange]: { handleEvent: (event: Event) => emit('fullscreenChange', event) },
58
- [VIDEO_DOM_EVENT_MAP.onWaiting]: { handleEvent: (event: Event) => emit('waiting', event) },
59
- [VIDEO_DOM_EVENT_MAP.onQualityChange]: { handleEvent: (event: Event) => emit('qualityChange', event) },
60
- [VIDEO_DOM_EVENT_MAP.onRateChange]: { handleEvent: (event: Event) => emit('rateChange', event) },
61
- };
62
-
63
- watch(elementRef, (element) => {
64
- boundElement = bindElementEvents(boundElement, element, videoEventListeners);
65
- });
66
-
67
- onBeforeUnmount(() => {
68
- unbindElementEvents(boundElement, videoEventListeners);
69
- });
70
-
71
- watch(
72
- [elementRef, () => props.rotate, () => props.objectFit],
73
- () => {
74
- const el = elementRef.value;
75
- if (!el) return;
76
- const rotate = props.rotate;
77
- if (rotate === undefined || rotate === null || rotate === '') {
78
- el.removeAttribute('rotate');
79
- } else {
80
- el.setAttribute('rotate', String(rotate).trim());
81
- }
82
- const objectFit = props.objectFit;
83
- if (objectFit === undefined || objectFit === null || objectFit === '') {
84
- el.removeAttribute('object-fit');
85
- } else {
86
- el.setAttribute('object-fit', String(objectFit).trim().toLowerCase());
87
- }
88
- },
89
- { immediate: true }
90
- );
91
-
92
- const domProps = computed(() => {
93
- const result = buildVideoNativeAttrs({
94
- ...props,
95
- id: resolvedId.value,
96
- }, attrs as Record<string, unknown>);
97
- return {
98
- ...result,
99
- class: props.class ?? attrs.class,
100
- style: props.style ?? attrs.style,
101
- };
102
- });
103
-
104
- defineExpose({ el: elementRef });
105
-
106
- const render = () => h('lx-video', { ref: elementRef, ...domProps.value });
107
- </script>
108
-
109
- <template>
110
- <render />
111
- </template>
package/src/vue/hook.ts DELETED
@@ -1,313 +0,0 @@
1
- import {
2
- onUnmounted,
3
- reactive,
4
- ref,
5
- unref,
6
- watch,
7
- type Ref,
8
- } from "vue";
9
- import type {
10
- LxChannel,
11
- LxBridgeError,
12
- LxStream,
13
- } from "@lingxia/bridge";
14
- import {
15
- ensurePageBridgeSubscription,
16
- getMethodKey,
17
- getPageActions,
18
- invokeMethod,
19
- resolveParams,
20
- stableParamKey,
21
- subscribePageData,
22
- toBridgeError,
23
- type ActionMap,
24
- type ChannelIn,
25
- type ChannelOut,
26
- type MethodParams,
27
- type ParamsSource,
28
- type Snapshot,
29
- type StreamData,
30
- type StreamResult,
31
- } from "../shared/runtime.js";
32
-
33
- type MethodSource<T> = T | Ref<T>;
34
-
35
- function resolveMethod<TMethod>(source: MethodSource<TMethod>): TMethod {
36
- return unref(source) as TMethod;
37
- }
38
-
39
- const reactiveSnapshot = reactive<Snapshot>({});
40
- let snapshotSubscribed = false;
41
-
42
- function ensureReactiveSnapshot(): void {
43
- if (snapshotSubscribed) return;
44
- snapshotSubscribed = true;
45
- subscribePageData((next) => {
46
- const normalized: Snapshot =
47
- next && typeof next === "object" ? (next as Snapshot) : {};
48
-
49
- for (const key of Object.keys(reactiveSnapshot)) {
50
- if (!Object.prototype.hasOwnProperty.call(normalized, key)) {
51
- delete reactiveSnapshot[key];
52
- }
53
- }
54
- Object.assign(reactiveSnapshot, normalized);
55
- });
56
- }
57
-
58
- export function useLxPage<
59
- TData = Snapshot,
60
- TActions extends ActionMap = ActionMap,
61
- >(): { data: TData; actions: TActions } {
62
- ensurePageBridgeSubscription();
63
- ensureReactiveSnapshot();
64
- return { data: reactiveSnapshot as TData, actions: getPageActions<TActions>() };
65
- }
66
-
67
- export interface LxStreamOptions<TData, TReduced> {
68
- params?: unknown | (() => unknown);
69
- manual?: boolean;
70
- reduce?: (accumulated: TReduced, chunk: TData) => TReduced;
71
- initial?: TReduced;
72
- }
73
-
74
- export interface LxStreamState<TData, TResult = unknown> {
75
- data: Ref<TData | undefined>;
76
- result: Ref<TResult | undefined>;
77
- error: Ref<LxBridgeError | undefined>;
78
- streaming: Ref<boolean>;
79
- cancel: () => void;
80
- start: () => void;
81
- }
82
-
83
- export function useLxStream<
84
- TMethod extends (...args: any[]) => LxStream<any, any>,
85
- TReduced = StreamData<TMethod>,
86
- >(
87
- method: MethodSource<TMethod>,
88
- options?: LxStreamOptions<StreamData<TMethod>, TReduced> & {
89
- params?: ParamsSource<MethodParams<TMethod>>;
90
- },
91
- ): LxStreamState<
92
- TReduced extends StreamData<TMethod> ? StreamData<TMethod> : TReduced,
93
- StreamResult<TMethod>
94
- > {
95
- type TData = StreamData<TMethod>;
96
- type TResult = StreamResult<TMethod>;
97
- type TOut = TReduced extends TData ? TData : TReduced;
98
-
99
- const data = ref<TOut | undefined>(
100
- (options?.reduce ? options.initial : undefined) as TOut | undefined,
101
- ) as Ref<TOut | undefined>;
102
- const result = ref<TResult | undefined>(undefined) as Ref<TResult | undefined>;
103
- const error = ref<LxBridgeError | undefined>(undefined);
104
- const streaming = ref(false);
105
-
106
- let handle: LxStream<TData, TResult> | null = null;
107
- let acc: TReduced | undefined = options?.initial;
108
- let runId = 0;
109
-
110
- function cancel(): void {
111
- runId += 1;
112
- handle?.cancel();
113
- handle = null;
114
- streaming.value = false;
115
- }
116
-
117
- function start(): void {
118
- handle?.cancel();
119
- const currentRunId = runId + 1;
120
- runId = currentRunId;
121
-
122
- acc = options?.initial;
123
- data.value = (options?.reduce ? options.initial : undefined) as TOut | undefined;
124
- result.value = undefined;
125
- error.value = undefined;
126
- streaming.value = true;
127
-
128
- let nextHandle: LxStream<TData, TResult>;
129
- try {
130
- const params = resolveParams(options?.params);
131
- nextHandle = invokeMethod(resolveMethod(method), params) as LxStream<TData, TResult>;
132
- } catch (err: unknown) {
133
- if (runId !== currentRunId) return;
134
- handle = null;
135
- error.value = toBridgeError(err);
136
- streaming.value = false;
137
- return;
138
- }
139
-
140
- handle = nextHandle;
141
-
142
- nextHandle.on("data", (chunk: TData) => {
143
- if (runId !== currentRunId) return;
144
- if (options?.reduce) {
145
- acc = options.reduce(acc as TReduced, chunk);
146
- data.value = acc as TOut;
147
- } else {
148
- data.value = chunk as unknown as TOut;
149
- }
150
- });
151
-
152
- nextHandle.on("end", (res: TResult) => {
153
- if (runId !== currentRunId) return;
154
- handle = null;
155
- result.value = res;
156
- streaming.value = false;
157
- });
158
-
159
- nextHandle.on("error", (err: LxBridgeError) => {
160
- if (runId !== currentRunId) return;
161
- handle = null;
162
- error.value = err;
163
- streaming.value = false;
164
- });
165
- }
166
-
167
- watch(
168
- () => {
169
- if (options?.manual) return null;
170
- const resolvedMethod = resolveMethod(method);
171
- return [
172
- getMethodKey(resolvedMethod) ?? resolvedMethod,
173
- stableParamKey(resolveParams(options?.params)),
174
- ];
175
- },
176
- () => {
177
- if (!options?.manual) {
178
- start();
179
- }
180
- },
181
- { immediate: !options?.manual },
182
- );
183
-
184
- onUnmounted(() => {
185
- runId += 1;
186
- handle?.cancel();
187
- handle = null;
188
- });
189
-
190
- return { data, result, error, streaming, cancel, start };
191
- }
192
-
193
- export interface LxChannelOptions {
194
- params?: unknown | (() => unknown);
195
- manual?: boolean;
196
- }
197
-
198
- export interface LxChannelState<TData, TOut = TData> {
199
- last: Ref<TData | undefined>;
200
- error: Ref<LxBridgeError | undefined>;
201
- connecting: Ref<boolean>;
202
- connected: Ref<boolean>;
203
- send: (payload: TOut) => void;
204
- close: (code?: string, reason?: string) => void;
205
- reopen: () => void;
206
- }
207
-
208
- export function useLxChannel<
209
- TMethod extends (...args: any[]) => Promise<LxChannel<any, any>>,
210
- >(
211
- method: MethodSource<TMethod>,
212
- options?: LxChannelOptions & {
213
- params?: ParamsSource<MethodParams<TMethod>>;
214
- },
215
- ): LxChannelState<ChannelIn<TMethod>, ChannelOut<TMethod>> {
216
- type TIn = ChannelIn<TMethod>;
217
- type TOut = ChannelOut<TMethod>;
218
-
219
- const last = ref<TIn | undefined>(undefined) as Ref<TIn | undefined>;
220
- const error = ref<LxBridgeError | undefined>(undefined);
221
- const connecting = ref(false);
222
- const connected = ref(false);
223
-
224
- let ch: LxChannel<TIn, TOut> | null = null;
225
- let runId = 0;
226
-
227
- function send(payload: TOut): void {
228
- ch?.send(payload);
229
- }
230
-
231
- function close(code?: string, reason?: string): void {
232
- runId += 1;
233
- ch?.close(code, reason);
234
- ch = null;
235
- connecting.value = false;
236
- connected.value = false;
237
- }
238
-
239
- function reopen(): void {
240
- ch?.close();
241
- ch = null;
242
-
243
- const thisRunId = ++runId;
244
- last.value = undefined;
245
- error.value = undefined;
246
- connecting.value = true;
247
- connected.value = false;
248
-
249
- Promise.resolve(
250
- invokeMethod(resolveMethod(method), resolveParams(options?.params)) as Promise<LxChannel<TIn, TOut>>,
251
- )
252
- .then((nextChannel) => {
253
- if (runId !== thisRunId) {
254
- nextChannel.close();
255
- return;
256
- }
257
- ch = nextChannel;
258
- connecting.value = false;
259
- connected.value = true;
260
-
261
- nextChannel.on("data", (payload) => {
262
- if (runId !== thisRunId) return;
263
- last.value = payload as TIn;
264
- });
265
-
266
- nextChannel.on("close", () => {
267
- if (runId !== thisRunId) return;
268
- ch = null;
269
- connecting.value = false;
270
- connected.value = false;
271
- });
272
-
273
- nextChannel.on("error", (err: LxBridgeError) => {
274
- if (runId !== thisRunId) return;
275
- ch = null;
276
- error.value = err;
277
- connecting.value = false;
278
- connected.value = false;
279
- });
280
- })
281
- .catch((err: unknown) => {
282
- if (runId !== thisRunId) return;
283
- error.value = toBridgeError(err);
284
- connecting.value = false;
285
- connected.value = false;
286
- });
287
- }
288
-
289
- watch(
290
- () => {
291
- if (options?.manual) return null;
292
- const resolvedMethod = resolveMethod(method);
293
- return [
294
- getMethodKey(resolvedMethod) ?? resolvedMethod,
295
- stableParamKey(resolveParams(options?.params)),
296
- ];
297
- },
298
- () => {
299
- if (!options?.manual) {
300
- reopen();
301
- }
302
- },
303
- { immediate: !options?.manual },
304
- );
305
-
306
- onUnmounted(() => {
307
- runId += 1;
308
- ch?.close();
309
- ch = null;
310
- });
311
-
312
- return { last, error, connecting, connected, send, close, reopen };
313
- }
package/src/vue/index.ts DELETED
@@ -1,22 +0,0 @@
1
- export {
2
- useLxPage,
3
- useLxStream,
4
- useLxChannel,
5
- type LxStreamOptions,
6
- type LxStreamState,
7
- type LxChannelOptions,
8
- type LxChannelState,
9
- } from "./hook.js";
10
- export { default as LxVideo } from "./LxVideo.vue";
11
- export { default as LxPicker } from "./LxPicker.vue";
12
- export { default as LxNavigator } from "./LxNavigator.vue";
13
- export { default as LxInput } from "./LxInput.vue";
14
- export { default as LxTextarea } from "./LxTextarea.vue";
15
- export type {
16
- LxVideoProps,
17
- LxPickerProps,
18
- LxNavigatorProps,
19
- LxNavigatorEvent,
20
- LxInputProps,
21
- LxTextareaProps,
22
- } from "./types.js";
@@ -1,5 +0,0 @@
1
- declare module '*.vue' {
2
- import type { DefineComponent } from 'vue';
3
- const component: DefineComponent<{}, {}, any>;
4
- export default component;
5
- }
@@ -1,33 +0,0 @@
1
- export function getCustomEventDetail<T>(event: Event): T {
2
- return ((event as CustomEvent).detail ?? {}) as T;
3
- }
4
-
5
- export function bindElementEvents(
6
- currentBoundElement: HTMLElement | null,
7
- nextElement: HTMLElement | null,
8
- listeners: Record<string, EventListenerObject>
9
- ): HTMLElement | null {
10
- if (currentBoundElement && currentBoundElement !== nextElement) {
11
- for (const [event, listener] of Object.entries(listeners)) {
12
- currentBoundElement.removeEventListener(event, listener);
13
- }
14
- currentBoundElement = null;
15
- }
16
- if (nextElement && currentBoundElement !== nextElement) {
17
- for (const [event, listener] of Object.entries(listeners)) {
18
- nextElement.addEventListener(event, listener);
19
- }
20
- currentBoundElement = nextElement;
21
- }
22
- return currentBoundElement;
23
- }
24
-
25
- export function unbindElementEvents(
26
- boundElement: HTMLElement | null,
27
- listeners: Record<string, EventListenerObject>
28
- ): void {
29
- if (!boundElement) return;
30
- for (const [event, listener] of Object.entries(listeners)) {
31
- boundElement.removeEventListener(event, listener);
32
- }
33
- }
package/src/vue/types.ts DELETED
@@ -1,107 +0,0 @@
1
- import type { CSSProperties } from 'vue';
2
- import type { LxVideoAttributes } from '@lingxia/elements';
3
- import type { LxNavigatorEvent, NavigatorOpenType, NavigatorTarget } from '@lingxia/elements';
4
-
5
- export interface LxVideoProps extends Omit<LxVideoAttributes, 'ref' | 'className' | 'style'> {
6
- class?: string;
7
- style?: CSSProperties;
8
- }
9
-
10
- export interface LxPickerProps {
11
- columns?: string[][] | [string[], Record<string, string[]>];
12
- mode?: 'date' | 'time';
13
- start?: string;
14
- end?: string;
15
- fields?: 'year' | 'month' | 'day' | 'range';
16
- modelValue?: string | string[];
17
- placeholder?: string;
18
- class?: string;
19
- style?: CSSProperties;
20
- disabled?: boolean;
21
- cancelText?: string;
22
- cancelTextColor?: string;
23
- cancelButtonColor?: string;
24
- confirmText?: string;
25
- confirmTextColor?: string;
26
- confirmButtonColor?: string;
27
- onChange?: (event: Event) => void;
28
- onNativeScroll?: (event: Event) => void;
29
- pageBindings?: Record<string, string>;
30
- }
31
-
32
- export interface LxNavigatorProps {
33
- url?: string;
34
- openType?: NavigatorOpenType;
35
- target?: NavigatorTarget;
36
- delta?: number;
37
- appId?: string;
38
- path?: string;
39
- phoneNumber?: string;
40
- hoverClass?: string;
41
- hoverStopPropagation?: boolean;
42
- hoverStartTime?: number;
43
- hoverStayTime?: number;
44
- class?: string;
45
- style?: CSSProperties;
46
- }
47
-
48
- export interface LxInputProps {
49
- id?: string;
50
- modelValue?: string;
51
- value?: string;
52
- defaultValue?: string;
53
- type?: 'text' | 'number' | 'password' | 'digit';
54
- password?: boolean;
55
- placeholder?: string;
56
- placeholderStyle?: string;
57
- placeholderClass?: string;
58
- maxlength?: number;
59
- cursorSpacing?: number;
60
- autoFocus?: boolean;
61
- disabled?: boolean;
62
- focus?: boolean;
63
- confirmType?: 'send' | 'search' | 'next' | 'go' | 'done';
64
- alwaysEmbed?: boolean;
65
- confirmHold?: boolean;
66
- cursor?: number;
67
- cursorColor?: string;
68
- selectionStart?: number;
69
- selectionEnd?: number;
70
- adjustPosition?: boolean;
71
- holdKeyboard?: boolean;
72
- class?: string;
73
- style?: CSSProperties;
74
- pageBindings?: Record<string, string>;
75
- }
76
-
77
- export interface LxTextareaProps {
78
- id?: string;
79
- modelValue?: string;
80
- value?: string;
81
- defaultValue?: string;
82
- placeholder?: string;
83
- placeholderStyle?: string;
84
- placeholderClass?: string;
85
- maxlength?: number;
86
- disabled?: boolean;
87
- autoFocus?: boolean;
88
- focus?: boolean;
89
- autoHeight?: boolean;
90
- cursorSpacing?: number;
91
- showConfirmBar?: boolean;
92
- adjustPosition?: boolean;
93
- holdKeyboard?: boolean;
94
- disableDefaultPadding?: boolean;
95
- confirmType?: 'send' | 'search' | 'next' | 'go' | 'done' | 'return';
96
- confirmHold?: boolean;
97
- fixed?: boolean;
98
- adjustKeyboardTo?: 'cursor' | 'bottom';
99
- cursor?: number;
100
- selectionStart?: number;
101
- selectionEnd?: number;
102
- class?: string;
103
- style?: CSSProperties;
104
- pageBindings?: Record<string, string>;
105
- }
106
-
107
- export type { LxNavigatorEvent };