subscriber修改了sub和unsub的接口形式

This commit is contained in:
Xu Chang 2024-07-17 21:41:50 +08:00
parent 7c44c999c8
commit 4dc20aff95
18 changed files with 110 additions and 95 deletions

View File

@ -2,6 +2,9 @@ import { assert } from 'oak-domain/lib/utils/assert';
import { getFilterName } from '../filter/utils';
export default OakComponent({
isList: true,
entity() {
return this.props.entity;
},
data: {
isExpandContent: false,
open: false,

View File

@ -25,8 +25,8 @@ export declare class SubScriber<ED extends EntityDict & BaseEntityDict> extends
private emit;
private initSocketPoint;
private connect;
sub(events: string[], moduleName: string, callback?: Callback<ED>): Promise<void>;
unsub(events: string[], moduleName: string): Promise<void>;
sub(events: string[], callback?: Callback<ED>): Promise<() => void>;
private unsub;
getSubscriberId(): string | undefined;
setHalted(halted: boolean): void;
}

View File

@ -82,9 +82,7 @@ export class SubScriber extends Feature {
socket.on('data', (opRecords, event) => {
const registered = this.eventMap[event];
if (registered) {
for (const moduleName in registered) {
registered[moduleName] && registered[moduleName](event, opRecords);
}
registered.callbacks.forEach((ele) => ele(event, opRecords));
}
this.cache.sync(opRecords);
});
@ -122,27 +120,30 @@ export class SubScriber extends Feature {
socket.connect();
});
}
async sub(events, moduleName, callback) {
async sub(events, callback) {
const newEvents = [];
events.forEach((event) => {
const registered = this.eventMap[event];
if (registered) {
assert(!registered.hasOwnProperty(moduleName), `[subscriber]注册回调的事件${event}和moduleName${moduleName}发生重复`);
registered[moduleName] = callback;
if (callback) {
registered.callbacks.push(callback);
registered.count++;
}
}
else {
this.eventMap[event] = {
[moduleName]: callback,
callbacks: callback ? [callback] : [],
count: 1,
};
newEvents.push(event);
}
;
});
if (this.socketState === 'unconnected') {
return this.connect();
await this.connect();
}
else if (this.socketState === 'connected' && newEvents.length > 0) {
return new Promise((resolve, reject) => {
await new Promise((resolve, reject) => {
this.socket.emit('sub', newEvents, (result) => {
if (result) {
this.message.setMessage({
@ -158,18 +159,26 @@ export class SubScriber extends Feature {
});
});
}
return () => {
this.unsub(events, callback);
};
}
async unsub(events, moduleName) {
const emptyEvents = [];
async unsub(events, callback) {
const invalidEvents = [];
events.forEach((event) => {
const registered = this.eventMap[event];
assert(registered.hasOwnProperty(moduleName));
unset(registered, moduleName);
if (Object.keys(registered).length === 0) {
emptyEvents.push(event);
assert(registered);
registered.count--;
if (registered.count > 0) {
if (callback) {
pull(registered.callbacks, callback);
}
}
else {
invalidEvents.push(event);
}
});
emptyEvents.forEach(event => unset(this.eventMap, event));
invalidEvents.forEach(event => unset(this.eventMap, event));
if (this.socketState === 'connected') {
this.socket.emit('unsub', events);
if (Object.keys(this.eventMap).length === 0) {

View File

@ -469,11 +469,8 @@ const oakBehavior = Behavior({
loadMissedLocales(key) {
this.features.locales.loadMissedLocale(key);
},
subDataEvents(events, moduleName, callback) {
return this.features.subscriber.sub(events, moduleName, callback);
},
unsubDataEvents(events, moduleName) {
return this.features.subscriber.unsub(events, moduleName);
subDataEvents(events, callback) {
return this.features.subscriber.sub(events, callback);
},
},
observers: {

3
es/page.react.d.ts vendored
View File

@ -101,8 +101,7 @@ export declare function createComponent<IsList extends boolean, ED extends Entit
getPagination(path?: string | undefined): import(".").Pagination | undefined;
setPageSize(pageSize: number, path?: string | undefined): void;
setCurrentPage(currentPage: number, path?: string | undefined): void;
subDataEvents(events: string[], moduleName: string, callback: (event: string, opRecords: OpRecord<ED>[]) => void): Promise<void>;
unsubDataEvents(events: string[], moduleName: string): Promise<void>;
subDataEvents(events: string[], callback: (event: string, opRecords: OpRecord<ED>[]) => void): Promise<() => void>;
context: unknown;
setState<K extends keyof TData | keyof FormedData | keyof import("./types/Page").OakComponentData<ED, T>>(state: ComponentData<ED, T, FormedData, TData> | ((prevState: Readonly<ComponentData<ED, T, FormedData, TData>>, props: Readonly<ComponentProps<ED, T, TProperty>>) => ComponentData<ED, T, FormedData, TData> | Pick<ComponentData<ED, T, FormedData, TData>, K> | null) | Pick<ComponentData<ED, T, FormedData, TData>, K> | null, callback?: (() => void) | undefined): void;
forceUpdate(callback?: (() => void) | undefined): void;

View File

@ -368,11 +368,8 @@ class OakComponentBase extends React.PureComponent {
this.features.runningTree.setCurrentPage(path2, currentPage);
}
}
subDataEvents(events, moduleName, callback) {
return this.features.subscriber.sub(events, moduleName, callback);
}
unsubDataEvents(events, moduleName) {
return this.features.subscriber.unsub(events, moduleName);
subDataEvents(events, callback) {
return this.features.subscriber.sub(events, callback);
}
}
function translateListeners(listeners) {

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

@ -184,8 +184,7 @@ export type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T
}[] | undefined;
refresh: (pageNumber?: number) => Promise<void>;
aggregate: (aggregation: ED[T]['Aggregation']) => Promise<AggregationResult<ED[T]['Schema']>>;
subDataEvents: (events: string[], moduleName: string, callback?: (event: string, opRecords: OpRecord<ED>[]) => void) => Promise<void>;
unsubDataEvents: (events: string[], moduleName: string) => Promise<void>;
subDataEvents: (events: string[], callback?: (event: string, opRecords: OpRecord<ED>[]) => void) => Promise<() => void>;
};
export type OakSingleComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
setId: (id: string) => void;

View File

@ -25,8 +25,8 @@ export declare class SubScriber<ED extends EntityDict & BaseEntityDict> extends
private emit;
private initSocketPoint;
private connect;
sub(events: string[], moduleName: string, callback?: Callback<ED>): Promise<void>;
unsub(events: string[], moduleName: string): Promise<void>;
sub(events: string[], callback?: Callback<ED>): Promise<() => void>;
private unsub;
getSubscriberId(): string | undefined;
setHalted(halted: boolean): void;
}

View File

@ -86,9 +86,7 @@ class SubScriber extends Feature_1.Feature {
socket.on('data', (opRecords, event) => {
const registered = this.eventMap[event];
if (registered) {
for (const moduleName in registered) {
registered[moduleName] && registered[moduleName](event, opRecords);
}
registered.callbacks.forEach((ele) => ele(event, opRecords));
}
this.cache.sync(opRecords);
});
@ -126,27 +124,30 @@ class SubScriber extends Feature_1.Feature {
socket.connect();
});
}
async sub(events, moduleName, callback) {
async sub(events, callback) {
const newEvents = [];
events.forEach((event) => {
const registered = this.eventMap[event];
if (registered) {
(0, assert_1.assert)(!registered.hasOwnProperty(moduleName), `[subscriber]注册回调的事件${event}和moduleName${moduleName}发生重复`);
registered[moduleName] = callback;
if (callback) {
registered.callbacks.push(callback);
registered.count++;
}
}
else {
this.eventMap[event] = {
[moduleName]: callback,
callbacks: callback ? [callback] : [],
count: 1,
};
newEvents.push(event);
}
;
});
if (this.socketState === 'unconnected') {
return this.connect();
await this.connect();
}
else if (this.socketState === 'connected' && newEvents.length > 0) {
return new Promise((resolve, reject) => {
await new Promise((resolve, reject) => {
this.socket.emit('sub', newEvents, (result) => {
if (result) {
this.message.setMessage({
@ -162,18 +163,26 @@ class SubScriber extends Feature_1.Feature {
});
});
}
return () => {
this.unsub(events, callback);
};
}
async unsub(events, moduleName) {
const emptyEvents = [];
async unsub(events, callback) {
const invalidEvents = [];
events.forEach((event) => {
const registered = this.eventMap[event];
(0, assert_1.assert)(registered.hasOwnProperty(moduleName));
(0, lodash_1.unset)(registered, moduleName);
if (Object.keys(registered).length === 0) {
emptyEvents.push(event);
(0, assert_1.assert)(registered);
registered.count--;
if (registered.count > 0) {
if (callback) {
(0, lodash_1.pull)(registered.callbacks, callback);
}
}
else {
invalidEvents.push(event);
}
});
emptyEvents.forEach(event => (0, lodash_1.unset)(this.eventMap, event));
invalidEvents.forEach(event => (0, lodash_1.unset)(this.eventMap, event));
if (this.socketState === 'connected') {
this.socket.emit('unsub', events);
if (Object.keys(this.eventMap).length === 0) {

View File

@ -472,11 +472,8 @@ const oakBehavior = Behavior({
loadMissedLocales(key) {
this.features.locales.loadMissedLocale(key);
},
subDataEvents(events, moduleName, callback) {
return this.features.subscriber.sub(events, moduleName, callback);
},
unsubDataEvents(events, moduleName) {
return this.features.subscriber.unsub(events, moduleName);
subDataEvents(events, callback) {
return this.features.subscriber.sub(events, callback);
},
},
observers: {

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

@ -101,8 +101,7 @@ export declare function createComponent<IsList extends boolean, ED extends Entit
getPagination(path?: string | undefined): import(".").Pagination | undefined;
setPageSize(pageSize: number, path?: string | undefined): void;
setCurrentPage(currentPage: number, path?: string | undefined): void;
subDataEvents(events: string[], moduleName: string, callback: (event: string, opRecords: OpRecord<ED>[]) => void): Promise<void>;
unsubDataEvents(events: string[], moduleName: string): Promise<void>;
subDataEvents(events: string[], callback: (event: string, opRecords: OpRecord<ED>[]) => void): Promise<() => void>;
context: unknown;
setState<K extends keyof TData | keyof FormedData | keyof import("./types/Page").OakComponentData<ED, T>>(state: ComponentData<ED, T, FormedData, TData> | ((prevState: Readonly<ComponentData<ED, T, FormedData, TData>>, props: Readonly<ComponentProps<ED, T, TProperty>>) => ComponentData<ED, T, FormedData, TData> | Pick<ComponentData<ED, T, FormedData, TData>, K> | null) | Pick<ComponentData<ED, T, FormedData, TData>, K> | null, callback?: (() => void) | undefined): void;
forceUpdate(callback?: (() => void) | undefined): void;

View File

@ -373,11 +373,8 @@ class OakComponentBase extends react_1.default.PureComponent {
this.features.runningTree.setCurrentPage(path2, currentPage);
}
}
subDataEvents(events, moduleName, callback) {
return this.features.subscriber.sub(events, moduleName, callback);
}
unsubDataEvents(events, moduleName) {
return this.features.subscriber.unsub(events, moduleName);
subDataEvents(events, callback) {
return this.features.subscriber.sub(events, callback);
}
}
function translateListeners(listeners) {

3
lib/types/Page.d.ts vendored
View File

@ -184,8 +184,7 @@ export type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T
}[] | undefined;
refresh: (pageNumber?: number) => Promise<void>;
aggregate: (aggregation: ED[T]['Aggregation']) => Promise<AggregationResult<ED[T]['Schema']>>;
subDataEvents: (events: string[], moduleName: string, callback?: (event: string, opRecords: OpRecord<ED>[]) => void) => Promise<void>;
unsubDataEvents: (events: string[], moduleName: string) => Promise<void>;
subDataEvents: (events: string[], callback?: (event: string, opRecords: OpRecord<ED>[]) => void) => Promise<() => void>;
};
export type OakSingleComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
setId: (id: string) => void;

View File

@ -6,6 +6,9 @@ import { RowWithActions, ReactComponentProps } from '../../types/Page';
export default OakComponent({
isList: true,
entity() {
return this.props.entity!;
},
data: {
isExpandContent: false,
open: false,

View File

@ -18,7 +18,10 @@ export class SubScriber<ED extends EntityDict & BaseEntityDict> extends Feature
url: string;
path: string;
}>;
private eventMap: Record<string, Record<string, Callback<ED> | undefined>> = {};
private eventMap: Record<string, {
callbacks: Callback<ED>[];
count: number;
}> = {};
private url?: string;
private path?: string;
@ -117,9 +120,9 @@ export class SubScriber<ED extends EntityDict & BaseEntityDict> extends Feature
(opRecords: OpRecord<ED>[], event: string) => {
const registered = this.eventMap[event];
if (registered) {
for (const moduleName in registered) {
registered[moduleName] && registered[moduleName]!(event, opRecords);
}
registered.callbacks.forEach(
(ele) => ele(event, opRecords)
);
}
this.cache.sync(opRecords);
}
@ -162,27 +165,30 @@ export class SubScriber<ED extends EntityDict & BaseEntityDict> extends Feature
});
}
async sub(events: string[], moduleName: string, callback?: Callback<ED>): Promise<void> {
async sub(events: string[], callback?: Callback<ED>): Promise<() => void> {
const newEvents: string[] = [];
events.forEach((event) => {
const registered = this.eventMap[event];
if (registered) {
assert(!registered.hasOwnProperty(moduleName), `[subscriber]注册回调的事件${event}和moduleName${moduleName}发生重复`);
registered[moduleName] = callback;
if (callback) {
registered.callbacks.push(callback);
registered.count ++;
}
}
else {
this.eventMap[event] = {
[moduleName]: callback,
callbacks: callback ? [callback] : [],
count: 1,
};
newEvents.push(event);
};
});
if (this.socketState === 'unconnected') {
return this.connect();
await this.connect();
}
else if (this.socketState === 'connected' && newEvents.length > 0) {
return new Promise(
await new Promise(
(resolve, reject) => {
this.socket!.emit('sub', newEvents, (result: string) => {
if (result) {
@ -200,21 +206,30 @@ export class SubScriber<ED extends EntityDict & BaseEntityDict> extends Feature
}
);
}
return () => {
this.unsub(events, callback);
};
}
async unsub(events: string[], moduleName: string) {
const emptyEvents: string[] = [];
private async unsub(events: string[], callback?: Callback<ED>) {
const invalidEvents: string[] = [];
events.forEach(
(event) => {
const registered = this.eventMap[event];
assert(registered!.hasOwnProperty(moduleName));
unset(registered, moduleName);
if (Object.keys(registered).length === 0) {
emptyEvents.push(event);
assert(registered);
registered.count --;
if (registered.count > 0) {
if (callback) {
pull(registered.callbacks, callback);
}
}
else {
invalidEvents.push(event);
}
}
);
emptyEvents.forEach(
invalidEvents.forEach(
event => unset(this.eventMap, event)
);

View File

@ -689,12 +689,8 @@ const oakBehavior = Behavior<
this.features.locales.loadMissedLocale(key);
},
subDataEvents(events, moduleName, callback) {
return this.features.subscriber.sub(events, moduleName, callback);
},
unsubDataEvents(events, moduleName) {
return this.features.subscriber.unsub(events, moduleName);
subDataEvents(events, callback) {
return this.features.subscriber.sub(events, callback);
},
},
observers: {

View File

@ -610,12 +610,8 @@ abstract class OakComponentBase<
}
}
subDataEvents(events: string[], moduleName: string, callback: (event: string, opRecords: OpRecord<ED>[]) => void) {
return this.features.subscriber.sub(events, moduleName, callback);
}
unsubDataEvents(events: string[], moduleName: string) {
return this.features.subscriber.unsub(events, moduleName);
subDataEvents(events: string[], callback: (event: string, opRecords: OpRecord<ED>[]) => void) {
return this.features.subscriber.sub(events, callback);
}
}

View File

@ -410,8 +410,8 @@ export type OakCommonComponentMethods<
aggregate: (
aggregation: ED[T]['Aggregation']
) => Promise<AggregationResult<ED[T]['Schema']>>;
subDataEvents: (events: string[], moduleName: string, callback?: (event: string, opRecords: OpRecord<ED>[]) => void) => Promise<void>;
unsubDataEvents: (events: string[], moduleName: string) => Promise<void>;
subDataEvents: (events: string[], callback?: (event: string, opRecords: OpRecord<ED>[]) => void) => Promise<() => void>;
// unsubDataEvents: (events: string[], moduleName: string) => Promise<void>;
};
export type OakSingleComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {