Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/data-client-manager/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ctrl.fetch(), ctrl.fetchIfStale(), ctrl.expireAll(), ctrl.invalidate(), ctrl.inv
ctrl.setError(), ctrl.resetEntireStore(), ctrl.subscribe(), ctrl.unsubscribe().

```ts
import type { Manager, Middleware } from '@data-client/core';
import type { Manager, Middleware } from '@data-client/react'; // or '@data-client/vue'
import CurrentTime from './CurrentTime';

export default class TimeManager implements Manager {
Expand Down
7 changes: 5 additions & 2 deletions .agents/skills/data-client-manager/references/Controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,11 @@ function useCache<E extends EndpointInterface>(
```

```tsx title="MyManager.ts"
import type { Manager, Middleware, actionTypes } from '@data-client/core';
import type { EndpointInterface } from '@data-client/endpoint';
import {
type Manager,
type Middleware,
actionTypes,
} from '@data-client/react';

export default class MyManager implements Manager {
middleware: Middleware = controller => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,11 @@ In event handlers, pass [getState()](#getState) to read the latest store, as in
[getState() example](#getState).

```tsx title="MyManager.ts"
import type { Manager, Middleware, actionTypes } from '@data-client/core';
import type { EndpointInterface } from '@data-client/endpoint';
import {
type Manager,
type Middleware,
actionTypes,
} from '@data-client/vue';

export default class MyManager implements Manager {
middleware: Middleware = controller => {
Expand Down
20 changes: 13 additions & 7 deletions .agents/skills/data-client-manager/references/Manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ The job of `middleware` is to dispatch actions, respond to [actions](./Actions.m
[Controller](./Controller.md) provides type-safe action dispatchers.

```ts title="CurrentTime"
import { Entity } from '@data-client/endpoint';
import { Entity } from '@data-client/rest';

export default class CurrentTime extends Entity {
id = 0;
Expand All @@ -190,11 +190,11 @@ export default class CurrentTime extends Entity {
```

```ts title="TimeManager"
import type { Manager, Middleware } from '@data-client/core';
import type { Manager, Middleware } from '@data-client/react';
import CurrentTime from './CurrentTime';

export default class TimeManager implements Manager {
protected declare intervalID?: ReturnType<typeof setInterval>;
declare protected intervalID?: ReturnType<typeof setInterval>;

middleware: Middleware = controller => {
this.intervalID = setInterval(() => {
Expand Down Expand Up @@ -253,20 +253,26 @@ encouraging safe access to its members.
In case we want to 'handle' a certain [action](./Actions.md), we can 'consume' it by not calling next.

```ts title="isEntity"
import type { Schema, EntityInterface } from '@data-client/core';
import type { Schema, EntityInterface } from '@data-client/react';

export default function isEntity(schema: Schema): schema is EntityInterface {
export default function isEntity(
schema: Schema,
): schema is EntityInterface {
return schema !== null && (schema as any).pk !== undefined;
}
```

```ts title="SubsManager"
import type { Manager, Middleware, EntityInterface } from '@data-client/react';
import type {
Manager,
Middleware,
EntityInterface,
} from '@data-client/react';
import { actionTypes } from '@data-client/react';
import isEntity from './isEntity';

export default class CustomSubsManager implements Manager {
protected declare entities: Record<string, EntityInterface>;
declare protected entities: Record<string, EntityInterface>;

middleware: Middleware = controller => next => async action => {
switch (action.type) {
Expand Down
26 changes: 16 additions & 10 deletions .agents/skills/data-client-manager/references/Manager.vue.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The job of `middleware` is to dispatch actions, respond to [actions](./Actions.v
[Controller](./Controller.vue.md) provides type-safe action dispatchers.

```ts title="CurrentTime"
import { Entity } from '@data-client/endpoint';
import { Entity } from '@data-client/rest';

export default class CurrentTime extends Entity {
id = 0;
Expand All @@ -89,11 +89,11 @@ export default class CurrentTime extends Entity {
```

```ts title="TimeManager"
import type { Manager, Middleware } from '@data-client/core';
import type { Manager, Middleware } from '@data-client/vue';
import CurrentTime from './CurrentTime';

export default class TimeManager implements Manager {
protected declare intervalID?: ReturnType<typeof setInterval>;
declare protected intervalID?: ReturnType<typeof setInterval>;

middleware: Middleware = controller => {
this.intervalID = setInterval(() => {
Expand All @@ -114,8 +114,8 @@ export default class TimeManager implements Manager {
`actionTypes` includes all constants to distinguish between different [actions](./Actions.vue.md).

```ts
import type { Manager, Middleware } from '@data-client/react';
import { actionTypes } from '@data-client/react';
import type { Manager, Middleware } from '@data-client/vue';
import { actionTypes } from '@data-client/vue';

export default class LoggingManager implements Manager {
middleware: Middleware = controller => next => async action => {
Expand Down Expand Up @@ -152,20 +152,26 @@ encouraging safe access to its members.
In case we want to 'handle' a certain [action](./Actions.vue.md), we can 'consume' it by not calling next.

```ts title="isEntity"
import type { Schema, EntityInterface } from '@data-client/core';
import type { Schema, EntityInterface } from '@data-client/vue';

export default function isEntity(schema: Schema): schema is EntityInterface {
export default function isEntity(
schema: Schema,
): schema is EntityInterface {
return schema !== null && (schema as any).pk !== undefined;
}
```

```ts title="SubsManager"
import type { Manager, Middleware, EntityInterface } from '@data-client/react';
import { actionTypes } from '@data-client/react';
import type {
Manager,
Middleware,
EntityInterface,
} from '@data-client/vue';
import { actionTypes } from '@data-client/vue';
import isEntity from './isEntity';

export default class CustomSubsManager implements Manager {
protected declare entities: Record<string, EntityInterface>;
declare protected entities: Record<string, EntityInterface>;

middleware: Middleware = controller => next => async action => {
switch (action.type) {
Expand Down
34 changes: 23 additions & 11 deletions .agents/skills/data-client-manager/references/managers.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ its [Controller](./Controller.md)
### Middleware logging

```typescript
import type { Manager, Middleware } from '@data-client/core';
import type { Manager, Middleware } from '@data-client/react';

export default class LoggingManager implements Manager {
middleware: Middleware = controller => next => async action => {
Expand Down Expand Up @@ -230,9 +230,14 @@ export default class PersistManager implements Manager {
}
```

```tsx
```tsx title="index.tsx"
import { DataProvider, getDefaultManagers } from '@data-client/react';
import { createRoot } from 'react-dom/client';
import { get } from 'idb-keyval';
import App from './App';
import PersistManager from './PersistManager';

const managers = [...getDefaultManagers(), new PersistManager()];
const initialState = await get('data-client');

createRoot(document.body).render(
Expand All @@ -250,14 +255,18 @@ we can maintain fresh data when the data updates are independent of user action.
price, or a real-time collaborative editor.

```typescript
import { type Manager, type Middleware, Controller } from '@data-client/react';
import type { Entity } from '@data-client/rest';
import type {
Manager,
Middleware,
Controller,
EntityInterface,
} from '@data-client/react';

export default class StreamManager implements Manager {
declare protected controller: Controller;
declare protected evtSource: WebSocket; // | EventSource;
declare protected createEventSource: () => WebSocket | EventSource;
declare protected entities: Record<string, typeof Entity>;
declare protected entities: Record<string, EntityInterface>;

constructor(
createEventSource: () => WebSocket | EventSource,
Expand All @@ -270,15 +279,19 @@ export default class StreamManager implements Manager {
middleware: Middleware = controller => {
this.controller = controller;
return next => async action => next(action);
}
};

connect() {
this.evtSource = this.createEventSource();
this.evtSource.onmessage = event => {
try {
const msg = JSON.parse(event.data);
if (msg.type in this.entities)
this.controller.set(this.entities[msg.type], ...msg.args, msg.data);
this.controller.set(
this.entities[msg.type],
...msg.args,
msg.data,
);
} catch (e) {
console.error('Failed to handle message');
console.error(e);
Expand Down Expand Up @@ -417,10 +430,9 @@ import { Ticker } from './Ticker';

export default function getManagers() {
return [
new StreamManager(
() => new WebSocket('wss://ws-feed.example.com'),
{ ticker: Ticker },
),
new StreamManager(() => new WebSocket('wss://ws-feed.example.com'), {
ticker: Ticker,
}),
...getDefaultManagers({
devToolsManager: {
// Increase latency buffer for high-frequency updates
Expand Down
Loading
Loading