subscriber支持setHalted

This commit is contained in:
wkj 2024-06-17 22:01:54 +08:00
parent bfd26c6e4d
commit b76906fd76
21 changed files with 79 additions and 52 deletions

View File

@ -117,9 +117,9 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
getProjection(): ED[T]["Selection"]["data"] | undefined;
private constructFilters;
constructSelection(withParent?: true, ignoreNewParent?: boolean, ignoreUnapplied?: true): {
data: ED[T]["Selection"]["data"];
data: ED[T]["Selection"]["data"] | undefined;
filter: ED[T]["Selection"]["filter"] | undefined;
sorter: ED[T]["Selection"]["sorter"];
sorter: ED[T]["Selection"]["sorter"] | undefined;
total: number | undefined;
indexFrom: number;
count: number;
@ -131,7 +131,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
refresh(pageNumber?: number, append?: boolean): Promise<void>;
loadMore(): Promise<void>;
setCurrentPage(currentPage: number): void;
clean(): void;
clean(dontPublish?: true): void;
getIntrinsticFilters(): ED[T]["Selection"]["filter"] | undefined;
}
declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof ED> extends Node<ED, T> {
@ -179,7 +179,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
private passRsToChild;
saveRefreshResult(data: Record<string, any>): void;
refresh(): Promise<void>;
clean(): void;
clean(dontPublish?: true): void;
private getFilter;
getIntrinsticFilters(): ED[T]["Selection"]["filter"] | undefined;
/**
@ -217,7 +217,7 @@ declare class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Featur
setExecuting(executing: boolean): void;
isExecuting(): boolean;
isLoading(): boolean;
clean(): void;
clean(dontPublish?: true): void;
checkIfClean(): void;
}
export type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
@ -315,7 +315,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends
} | {
message: string;
}>;
clean(path: string): void;
clean(path: string, dontPublish?: true): void;
getRoot(): Record<string, SingleNode<ED, keyof ED> | ListNode<ED, keyof ED> | VirtualNode<ED>>;
}
export {};

View File

@ -509,7 +509,7 @@ class ListNode extends Node {
$in: ids2,
}
} : undefined);
if (filter2) {
if (filter2 && data) {
const result = this.cache.get(this.entity, {
data,
filter: inModi ? filter : {
@ -838,15 +838,17 @@ class ListNode extends Node {
setCurrentPage(currentPage) {
this.refresh(currentPage, false);
}
clean() {
clean(dontPublish) {
if (this.dirty) {
const originUpdates = this.updates;
this.updates = {};
for (const k in this.children) {
this.children[k].clean();
this.children[k].clean(dontPublish);
}
this.dirty = undefined;
this.publish();
if (!dontPublish) {
this.publish();
}
}
}
// 查看这个list上所有数据必须遵守的限制
@ -1114,14 +1116,14 @@ class SingleNode extends Node {
if (attr === 'entityId') {
assert(data.entity, '设置entityId时请将entity也传入');
if (this.children[data.entity]) {
this.children[data.entity].clean();
this.children[data.entity].clean(true);
this.passRsToChild(data.entity);
}
}
else if (this.schema[this.entity].attributes[attr]?.type === 'ref') {
const refKey = attr.slice(0, attr.length - 2);
if (this.children[refKey]) {
this.children[refKey].clean();
this.children[refKey].clean(true);
this.passRsToChild(refKey);
}
}
@ -1328,14 +1330,16 @@ class SingleNode extends Node {
this.publish();
}
}
clean() {
clean(dontPublish) {
if (this.dirty) {
this.operation = undefined;
for (const child in this.children) {
this.children[child].clean();
this.children[child].clean(dontPublish);
}
this.dirty = undefined;
this.publish();
if (!dontPublish) {
this.publish();
}
}
}
getFilter() {
@ -1547,12 +1551,14 @@ class VirtualNode extends Feature {
isLoading() {
return this.loading;
}
clean() {
clean(dontPublish) {
for (const ele in this.children) {
this.children[ele].clean();
this.children[ele].clean(dontPublish);
}
this.dirty = false;
this.publish();
if (!dontPublish) {
this.publish();
}
}
checkIfClean() {
for (const k in this.children) {
@ -2041,7 +2047,7 @@ export class RunningTree extends Feature {
.filter((ele) => !!ele)
.map((ele) => ele.operation), undefined, () => {
// 清空缓存
node.clean();
node.clean(true);
if (node instanceof SingleNode) {
assert(operations.length === 1);
// 这逻辑有点扯,页面自己决定后续逻辑 by Xc 20231108
@ -2055,7 +2061,7 @@ export class RunningTree extends Feature {
});
return result;
}
node.clean();
node.clean(true);
node.setExecuting(false);
return { message: 'No Operation' };
}
@ -2067,9 +2073,9 @@ export class RunningTree extends Feature {
throw err;
}
}
clean(path) {
clean(path, dontPublish) {
const node = this.findNode(path);
node.clean();
node.clean(dontPublish);
const parent = node.getParent();
if (parent) {
parent.checkIfClean();

View File

@ -13,6 +13,7 @@ export declare class SubScriber<ED extends EntityDict & BaseEntityDict> extends
private url?;
private path?;
private socket?;
private halted;
private socketState;
private eventCallbackMap;
constructor(cache: Cache<ED>, message: Message, getSubscribePointFn: () => Promise<{
@ -27,5 +28,6 @@ export declare class SubScriber<ED extends EntityDict & BaseEntityDict> extends
sub(events: string[], moduleName: string, callback?: Callback<ED>): Promise<void>;
unsub(events: string[], moduleName: string): Promise<void>;
getSubscriberId(): string | undefined;
setHalted(halted: boolean): void;
}
export {};

View File

@ -10,6 +10,7 @@ export class SubScriber extends Feature {
url;
path;
socket;
halted;
socketState = 'unconnected';
eventCallbackMap = {
connect: [],
@ -20,6 +21,7 @@ export class SubScriber extends Feature {
this.cache = cache;
this.message = message;
this.getSubscribePointFn = getSubscribePointFn;
this.halted = false;
}
on(event, callback) {
this.eventCallbackMap[event].push(callback);
@ -36,6 +38,9 @@ export class SubScriber extends Feature {
this.path = path;
}
async connect() {
if (this.halted) {
return;
}
this.socketState = 'connecting';
let optionInited = false;
if (!this.url) {
@ -133,9 +138,6 @@ export class SubScriber extends Feature {
if (this.socketState === 'unconnected') {
return this.connect();
}
else if (this.socketState === 'connecting') {
return this.connect();
}
else if (this.socketState === 'connected' && newEvents.length > 0) {
return new Promise((resolve, reject) => {
this.socket.emit('sub', newEvents, (result) => {
@ -179,4 +181,10 @@ export class SubScriber extends Feature {
return this.socket.id;
}
}
setHalted(halted) {
this.halted = halted;
if (halted === false && Object.keys(this.eventMap).length > 0) {
this.connect();
}
}
}

View File

@ -160,11 +160,11 @@ const oakBehavior = Behavior({
switchTab(option, state) {
return this.features.navigator.switchTab(option, state);
},
clean(path) {
clean(dontPublish, path) {
const path2 = path
? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath;
return this.features.runningTree.clean(path2);
return this.features.runningTree.clean(path2, dontPublish);
},
isDirty(path) {
return this.features.runningTree.isDirty(path || this.state.oakFullpath);

2
es/types/Page.d.ts vendored
View File

@ -156,7 +156,7 @@ export type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T
navigateBack: (delta?: number) => Promise<void>;
redirectTo: <T2 extends keyof ED>(options: Parameters<typeof wx.redirectTo>[0] & OakNavigateToParameters<ED, T2>, state?: Record<string, any>, disableNamespace?: boolean) => Promise<void>;
switchTab: <T2 extends keyof ED>(options: Parameters<typeof wx.switchTab>[0] & OakNavigateToParameters<ED, T2>, state?: Record<string, any>, disableNamespace?: boolean) => Promise<void>;
clean: (path?: string) => void;
clean: (dontPublish?: true, path?: string) => void;
isDirty: (path?: string) => boolean;
t(key: string, params?: object): string;
execute: (action?: ED[T]['Action'], messageProps?: boolean | MessageProps, path?: string, opers?: Array<{

View File

@ -119,7 +119,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
constructSelection(withParent?: true, ignoreNewParent?: boolean, ignoreUnapplied?: true): {
data: ED[T]["Selection"]["data"] | undefined;
filter: ED[T]["Selection"]["filter"] | undefined;
sorter: ED[T]["Selection"]["sorter"];
sorter: ED[T]["Selection"]["sorter"] | undefined;
total: number | undefined;
indexFrom: number;
count: number;
@ -315,7 +315,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends
} | {
message: string;
}>;
clean(path: string): void;
clean(path: string, dontPublish?: true): void;
getRoot(): Record<string, SingleNode<ED, keyof ED> | ListNode<ED, keyof ED> | VirtualNode<ED>>;
}
export {};

View File

@ -512,7 +512,7 @@ class ListNode extends Node {
$in: ids2,
}
} : undefined);
if (filter2) {
if (filter2 && data) {
const result = this.cache.get(this.entity, {
data,
filter: inModi ? filter : {
@ -727,13 +727,13 @@ class ListNode extends Node {
const { sorters, getTotal } = this;
const data = this.getProjection();
// assert(data, '取数据时找不到projection信息');
const sorterArr = sorters.filter(ele => !ignoreUnapplied || ele.applied).map((ele) => {
const sorterArr = sorters.length > 0 ? sorters.filter(ele => !ignoreUnapplied || ele.applied).map((ele) => {
const { sorter } = ele;
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}).flat().filter((ele) => !!ele);
}).flat().filter((ele) => !!ele) : undefined;
const filters = this.constructFilters(withParent, ignoreNewParent, ignoreUnapplied);
const filters2 = filters?.filter((ele) => !!ele);
const filter = filters2 ? (0, filter_1.combineFilters)(this.entity, this.schema, filters2) : undefined;
@ -2076,9 +2076,9 @@ class RunningTree extends Feature_1.Feature {
throw err;
}
}
clean(path) {
clean(path, dontPublish) {
const node = this.findNode(path);
node.clean();
node.clean(dontPublish);
const parent = node.getParent();
if (parent) {
parent.checkIfClean();

View File

@ -13,6 +13,7 @@ export declare class SubScriber<ED extends EntityDict & BaseEntityDict> extends
private url?;
private path?;
private socket?;
private halted;
private socketState;
private eventCallbackMap;
constructor(cache: Cache<ED>, message: Message, getSubscribePointFn: () => Promise<{
@ -27,5 +28,6 @@ export declare class SubScriber<ED extends EntityDict & BaseEntityDict> extends
sub(events: string[], moduleName: string, callback?: Callback<ED>): Promise<void>;
unsub(events: string[], moduleName: string): Promise<void>;
getSubscriberId(): string | undefined;
setHalted(halted: boolean): void;
}
export {};

View File

@ -14,6 +14,7 @@ class SubScriber extends Feature_1.Feature {
url;
path;
socket;
halted;
socketState = 'unconnected';
eventCallbackMap = {
connect: [],
@ -24,6 +25,7 @@ class SubScriber extends Feature_1.Feature {
this.cache = cache;
this.message = message;
this.getSubscribePointFn = getSubscribePointFn;
this.halted = false;
}
on(event, callback) {
this.eventCallbackMap[event].push(callback);
@ -40,6 +42,9 @@ class SubScriber extends Feature_1.Feature {
this.path = path;
}
async connect() {
if (this.halted) {
return;
}
this.socketState = 'connecting';
let optionInited = false;
if (!this.url) {
@ -137,9 +142,6 @@ class SubScriber extends Feature_1.Feature {
if (this.socketState === 'unconnected') {
return this.connect();
}
else if (this.socketState === 'connecting') {
return this.connect();
}
else if (this.socketState === 'connected' && newEvents.length > 0) {
return new Promise((resolve, reject) => {
this.socket.emit('sub', newEvents, (result) => {
@ -183,5 +185,11 @@ class SubScriber extends Feature_1.Feature {
return this.socket.id;
}
}
setHalted(halted) {
this.halted = halted;
if (halted === false && Object.keys(this.eventMap).length > 0) {
this.connect();
}
}
}
exports.SubScriber = SubScriber;

View File

@ -1,6 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackendRuntimeContext = exports.FrontendRuntimeContext = void 0;
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./types/Feature"), exports);
tslib_1.__exportStar(require("./types/Notification"), exports);
@ -11,4 +10,4 @@ tslib_1.__exportStar(require("./types/AbstractComponent"), exports);
tslib_1.__exportStar(require("./types/Exception"), exports);
tslib_1.__exportStar(require("./types/Pagination"), exports);
tslib_1.__exportStar(require("./types/NamedCondition"), exports);
tslib_1.__exportStar(require("./types/ErrorPage"), exports);
tslib_1.__exportStar(require("./types/ErrorPage"), exports);

View File

@ -5,4 +5,4 @@ import { Feature } from './types/Feature';
import { DataOption, OakComponentOption } from './types/Page';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
export declare function createComponent<IsList extends boolean, ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, AsyncContext<ED>>>, FD extends Record<string, Feature>, FormedData extends Record<string, any>, TData extends Record<string, any> = {}, TProperty extends DataOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod>, features: BasicFeatures<ED> & FD): (props: any) => any;
export declare function createComponent<IsList extends boolean, ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, AsyncContext<ED>>>, FD extends Record<string, Feature>, FormedData extends Record<string, any>, TData extends Record<string, any> = {}, TProperty extends DataOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod>, features: BasicFeatures<ED> & FD): (props: any) => import("react/jsx-runtime").JSX.Element;

3
lib/page.web.d.ts vendored
View File

@ -1,3 +1,4 @@
import React from 'react';
import { Aspect, EntityDict } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { BasicFeatures } from './features';
@ -5,4 +6,4 @@ import { Feature } from './types/Feature';
import { DataOption, OakComponentOption } from './types/Page';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
export declare function createComponent<IsList extends boolean, ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, AsyncContext<ED>>>, FD extends Record<string, Feature>, FormedData extends Record<string, any>, TData extends Record<string, any> = {}, TProperty extends DataOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod>, features: BasicFeatures<ED> & FD): any;
export declare function createComponent<IsList extends boolean, ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, AsyncContext<ED>>>, FD extends Record<string, Feature>, FormedData extends Record<string, any>, TData extends Record<string, any> = {}, TProperty extends DataOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod>, features: BasicFeatures<ED> & FD): React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;

View File

@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.createComponent = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importDefault(require("react"));
const withRouter_1 = tslib_1.__importDefault(require("./platforms/web/router/withRouter"));
const PullToRefresh_1 = tslib_1.__importDefault(require("./platforms/web/PullToRefresh"));
const page_react_1 = require("./page.react");

View File

@ -4,6 +4,6 @@ type Props = {
features: Record<string, Feature>;
children: React.ReactNode;
};
declare const FeaturesProvider: (props: Props) => any;
declare const useFeatures: <FD2 extends Record<string, Feature>>() => any;
declare const FeaturesProvider: (props: Props) => import("react/jsx-runtime").JSX.Element;
declare const useFeatures: <FD2 extends Record<string, Feature>>() => FD2;
export { FeaturesProvider, useFeatures };

View File

@ -1,6 +1,7 @@
import React from 'react';
type OakComponentProperties = {
path?: string;
properties?: Record<string, any>;
};
declare const withRouter: (Component: React.ComponentType<any>, { path, properties }: OakComponentProperties) => (props: any) => any;
declare const withRouter: (Component: React.ComponentType<any>, { path, properties }: OakComponentProperties) => (props: any) => import("react/jsx-runtime").JSX.Element;
export default withRouter;

View File

@ -1,8 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importDefault(require("react"));
const assert_1 = require("oak-domain/lib/utils/assert");
function getParams(params, properties) {
const props = getProps(params, properties);

View File

@ -2,7 +2,6 @@
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importDefault(require("react"));
const rmc_pull_to_refresh_1 = tslib_1.__importDefault(require("rmc-pull-to-refresh"));
require("./PullToRefresh.css");
const OakPullToRefresh = (props) => {

View File

@ -4,5 +4,5 @@ declare const FeaturesProvider: React.FC<{
features: Record<string, Feature>;
children: React.ReactNode;
}>;
declare const useFeatures: <FD2 extends Record<string, Feature>>() => any;
declare const useFeatures: <FD2 extends Record<string, Feature>>() => FD2;
export { FeaturesProvider, useFeatures };

View File

@ -1,3 +1,4 @@
import React from 'react';
export type Width = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
export type Keys = Width[];
export type Values = {
@ -15,4 +16,6 @@ export type Breakpoints = {
export declare const keys: Keys;
export declare const values: Values;
export declare const defaultBreakpoints: Breakpoints;
export declare const ResponsiveContext: any;
export declare const ResponsiveContext: React.Context<{
breakpoints?: Breakpoints | undefined;
}>;

View File

@ -1,6 +1,7 @@
import React from 'react';
type OakComponentProperties = {
path?: string;
properties?: Record<string, any>;
};
declare const withRouter: (Component: React.ComponentType<any>, { path, properties }: OakComponentProperties) => any;
declare const withRouter: (Component: React.ComponentType<any>, { path, properties }: OakComponentProperties) => React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
export default withRouter;