0.20.16 • Published 24 days ago

dehub v0.20.16

Weekly downloads
-
License
MIT
Repository
github
Last release
24 days ago

Introduction

Note: As the project is not yet fully completed, there is still a risk of code refactoring. Please use with caution. The following only provides simple examples of usage. Detailed documentation will be provided upon official release.

DEHub attempts to be a message-driven library for JavaScript-based clients. It unifies the handling of events and data in all clients by using messages for subscription and processing. This allows all components and business processes in a page to handle business logic in a subscribable manner, and enables access to all registered components through context.

Features:

  • Supports component registration
  • Allows accessing all registered components in callback functions for event subscriptions
  • Supports data subscription
  • Supports singleton maintenance for data, ensuring that the same data request is only completed on one instance (this is important)
  • Supports data set loading
    • Supports serial loading of data sets

Component Registration

test('Register a component', async () => {
    // Component tag, used for referencing the component
    const tags = { id: 'cmp1' };
    // Register the component and use SessionDB to store component information
    let comp1 = new DEComp<any>(tags);
    await RegComponent(comp1);
    // Update the component state
    await comp1.update({ a: 1, b: 'abc' });
    // Check the updates
    expect(comp1.state.a).toBe(2); // X by default, this test will not pass
    expect(comp1.state.b).toBe('abc');
});

Event Subscription

To make the 'test' in the component test above pass, you can use 'when' to subscribe to the specified event, and update the value of 'a' to 2 after the 'update' is called.

when({ id: 'cmp1', event: EventNames.StateChanged, stage: EventStage.PostOperation },
    (context: EventContext) => {
        const comp1 = context.sender as DEComp;
        // You can also retrieve the registered component using the following method:
        // const comp1 = context.compoents[ObjPath({id:'user1'})];
        comp1.update({ a: 2 });
    });

Data Subscription

const IdTag = (entity: string, id: string): ObjTag => {
    const tag: ObjTag = { entity, id };
    return tag;
};


test('Modify and submit data', async () => {
    // Data object tag, with user id as 'user1'
    const user1Tag = IdTag('user.demo@org0', 'user1');
    // Subscribe to the data
    const user1Data = DEData(user1Tag);
    // Wait for data to finish loading
    await sleep(50);
    expect(user1Data.get('name')).toBe('Jim');
    // Change the data properties, note that the updated values will be stored in 'dirty'
    user1Data.set("age", 18);
    user1Data.set("name", 'Jim2');
    user1Data.set("att1", 'a');
    user1Data.set("att2", new Date());
    // Wait for the update to complete
    await sleep(20);
    // Check the updated results, 'get' by default includes the values in 'dirty'
    expect(user1Data.get('age')).toBe(18);
    expect(user1Data.get('name')).toBe('Jim2');
    expect(user1Data.get('att1')).toBe('a');
    // 'dirty' stores the unsaved data
    expect(user1Data.dirty('age')).toBe(18);
    expect(user1Data.dirty('att1')).toBe('a');
    // 'original' still stores the original data; note that 'get' will return 'Jim2' at this point
    expect(user1Data.original('name')).toBe('Jim');
    // Submit the data
    await user1Data.submit();
    // After submission, the data in 'dirty' will be cleared
    expect(user1Data.dirty('age')).toBeUndefined();
    // The latest data is now in 'original'
    expect(user1Data.original('name')).toBe('Jim2');
}, 2000);


/**
 * When loading 'user1', simulate providing the data for 'user1';
 */
when({ entity: 'user.demo@org0', id: 'user1', status: DataStatus.Loading }, 
    (context: EventContext) => {
        context.output.data = { name: 'Jim' };
});


/**
 * When submitting 'user1', simulate returning the submission result to 'context.output.data';
 */
when({
    entity: 'user.demo@org0',
    id: 'user1',
    event: EventNames.Submit,
    status: DataStatus.Uploading,
    stage: EventStage.PreOperation
},
    (context: EventContext) => {
        const sender: DEData = context.sender as DEData;
        if (!sender) return;
        context.output.data = sender.data;
    });

介绍

注意:因项目未列发完成,代码仍有重构风险,谨慎使用,以下仅提供简单的调用示例,待正式发布时提供详细的文档。

DEHub尝试作为基于js的客户端的消息驱动库,将所有客户端的事件与数据变统一由消息的形式进行订阅处理,以便页面中的所有组件及业务流程能够订阅的方式处理业务逻辑,并能够通过上下文访问所有已注册组件。

特性:

  • 支持组件注册
  • 支持在事件订阅的回调中访问所有注册的组件
  • 支持订阅数据
  • 支持数据单例维护,所有相同的数据请求只会在一个实例上完成,这个很重要;
  • 支持数据集加载
    • 支持数据集串行加载

组件的注册

test('注册一个组件', async () => {
	//组件标签,可用于引用组件
	const tags = { id: 'cmp1' };
	//注册组件,并使用SessionDB存储组件信息
	let comp1 = new DEComp<any>(tags);
    await RegComponent(comp1);
	//更新组件state
	await comp1.update({ a: 1, b: 'abc' });
	//检查更新检查
	expect(comp1.state.a).toBe(2);		// X 默认,该处无法通过测试
	expect(comp1.state.b).toBe('abc');
});

事件订阅

想让上面的组件测试中的test测试通过,可以用when来订阅指定事件,并在更新update后,更新a值为2。

when({ id: 'cmp1', event: EventNames.StateChanged, stage: EventStage.PostOperation },
	(context: EventContext) => {
		const comp1 = context.sender as DEComp;
		// 也可以通过以下方式获取注册的组件;
		//const comp1 = context.compoents[ObjPath({id:'user1'})];
		comp1.update({ a: 2 });
	});

数据订阅

const IdTag = (entity: string, id: string): ObjTag => {
    const tag: ObjTag = { entity, id };
    return tag;
};


test('数据修改并提交', async () => {
    //数据对象标签,用户id为user1
    const user1Tag = IdTag('user.demo@org0', 'user1');
    //订阅数据
    const user1Data = DEData(user1Tag);
    //等待数据加载完成
    await sleep(50);
    expect(user1Data.get('name')).toBe('Jim');
    //变更数据属性值,注意:该处更新的值都会进入dirty中;
    user1Data.set("age", 18);
    user1Data.set("name", 'Jim2');
    user1Data.set("att1", 'a');
    user1Data.set("att2", new Date());
    //等待更新完成
    await sleep(20);
    //判断更新结果,默认get取值包含了脏数据的值 ;
    expect(user1Data.get('age')).toBe(18);
    expect(user1Data.get('name')).toBe('Jim2');
    expect(user1Data.get('att1')).toBe('a');
    //在脏数据dirty保存未提交的数据
    expect(user1Data.dirty('age')).toBe(18);
    expect(user1Data.dirty('att1')).toBe('a');
    //原数据仍保存在original,注意,此时直接用get获取name是Jim2
    expect(user1Data.original('name')).toBe('Jim');
    //提交数据
    await user1Data.submit();
    //提交完成后,dirty的数据会被清空
    expect(user1Data.dirty('age')).toBeUndefined();
    //此时最新数据更新到original中
    expect(user1Data.original('name')).toBe('Jim2');
}, 2000);


/**
 * 加载user1时,模拟提供user1的数据;
 */
when({ entity: 'user.demo@org0', id: 'user1', status: DataStatus.Loading }, 
    (context: EventContext) => {
    context.output.data = { name: 'Jim' };
});

/**
 * 
 * 提交user1时,模拟返回提交成功到context.output.data中;
 */
when({
    entity: 'user.demo@org0',
    id: 'user1',
    event: EventNames.Submit,
    status: DataStatus.Uploading,
    stage: EventStage.PreOperation
},
    (context: EventContext) => {
        const sender: DEData = context.sender as DEData;
        if (!sender) return;
        context.output.data = sender.data;
    });
0.20.16

24 days ago

0.20.15

1 month ago

0.20.14

2 months ago

0.20.13

2 months ago

0.20.11

2 months ago

0.20.12

2 months ago

0.20.10

2 months ago

0.20.9

2 months ago

0.20.8

2 months ago

0.20.7

3 months ago

0.20.6

3 months ago

0.20.5

3 months ago

0.20.3

3 months ago

0.20.2

4 months ago

0.20.1

4 months ago

0.20.0

4 months ago

0.19.1

4 months ago

0.19.2

4 months ago

0.19.3

4 months ago

0.19.0

4 months ago

0.18.6

4 months ago

0.18.7

4 months ago

0.18.3

4 months ago

0.18.5

4 months ago

0.18.1

5 months ago

0.18.2

4 months ago

0.18.0

5 months ago

0.17.16

5 months ago

0.17.17

5 months ago

0.17.15

5 months ago

0.17.13

5 months ago

0.17.12

5 months ago

0.17.11

5 months ago

0.17.10

5 months ago

0.17.9

5 months ago

0.17.8

5 months ago

0.17.7

5 months ago

0.17.6

5 months ago

0.17.5

5 months ago

0.17.3

5 months ago

0.17.2

5 months ago

0.17.1

5 months ago

0.17.0

5 months ago

0.16.8

5 months ago

0.16.7

6 months ago

0.16.6

6 months ago

0.16.5

6 months ago

0.16.3

6 months ago

0.16.2

6 months ago

0.16.1

6 months ago

0.16.0

6 months ago

0.15.2

6 months ago

0.15.1

6 months ago

0.15.0

6 months ago

0.14.8

6 months ago

0.14.7

6 months ago

0.14.6

6 months ago

0.14.5

6 months ago

0.14.3

6 months ago

0.14.2

6 months ago

0.14.1

6 months ago

0.14.0

6 months ago

0.13.5

6 months ago

0.13.3

6 months ago

0.13.2

6 months ago

0.13.1

6 months ago

0.13.0

6 months ago

0.12.10

6 months ago

0.12.9

6 months ago

0.12.8

6 months ago

0.12.7

6 months ago

0.12.6

6 months ago

0.12.5

6 months ago

0.12.3

7 months ago

0.12.2

7 months ago

0.12.1

7 months ago

0.12.0

7 months ago

0.11.2

7 months ago

0.11.1

7 months ago

0.11.0

7 months ago

0.10.11

7 months ago

0.10.10

7 months ago

0.10.9

7 months ago

0.10.8

7 months ago

0.10.7

7 months ago

0.10.6

7 months ago

0.10.5

7 months ago

0.10.3

7 months ago

0.10.2

7 months ago

0.10.1

7 months ago

0.10.0

7 months ago

0.9.9

7 months ago

0.9.8

7 months ago

0.9.7

7 months ago

0.9.6

7 months ago

0.9.5

7 months ago

0.9.3

7 months ago

0.9.2

7 months ago

0.9.1

7 months ago

0.9.0

7 months ago

0.8.5

7 months ago

0.8.3

7 months ago

0.8.2

7 months ago

0.8.1

7 months ago

0.8.0

7 months ago

0.7.7

8 months ago

0.7.6

8 months ago

0.7.5

8 months ago

0.7.3

8 months ago

0.7.2

8 months ago

0.7.1

8 months ago

0.7.0

8 months ago

0.6.6

8 months ago

0.6.5

8 months ago

0.6.3

8 months ago

0.6.2

8 months ago

0.6.1

8 months ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago