Skip to content

Commit

Permalink
Merge pull request #35 from SICKAG/missing-ts-types
Browse files Browse the repository at this point in the history
add missing type
  • Loading branch information
WanjaTschuorSICKAG authored Nov 5, 2023
2 parents 0100385 + 82d791d commit 77617a7
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## next minor
### Fixed
- types export in package.json

### Added
- Add and export ServiceTopics type

## 0.2.9
### Fixed
- #16 an error is no longer thrown if a non-collage application is used as collage-fragment and removed from DOM
Expand Down
116 changes: 115 additions & 1 deletion docs/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,123 @@ npm run dev

cd ../todos

npm run dev --port 4000
npm run dev -- --port 4000
```

:::tip
If you want to learn more about the [concepts](../docs/concepts/) and [features](../docs/features/) or the [API](../docs/core-api/) of Collage, please have a look at our Docs.
:::

## Typescript

Of course, collage is typed and you can use it in your typescript projects.
The above example then looks like this.

:::: code-group
::: code-group-item dashboard/main.ts

```typescript
import { ContextApi, ServiceTopic, expose } from '@collage/core'
const context = await expose({
services: {
todos: {
topics: ['active']
}
}
}) as ContextApi & { topics: MyTopics }


// Declare the custom topics we want to use in our app
type MyTopics = {
todos: {
active: ServiceTopic
}
}

const activeTodos = context.topics.todos.active;

// whenever the active todos change, we want to react to that and disable the
// 'add-todo' buttons on the issues matching those
activeTodos.subscribe(todos => {
for (const details of [...document.querySelectorAll('details')]) {
const summary = details.querySelector('summary')
const button = details.querySelector('[data-action=add-todo]') as HTMLButtonElement
if (button && summary) {
button.disabled = (todos as string[]).includes(summary.textContent!)
}
}
})


document.addEventListener('click', ({ target }) => {
if (target instanceof Element && target.closest('[data-action=add-todo]')) {
const name = target.closest('details')!.querySelector('summary')!.textContent
// since we added a name to the 'davinci-fragment' in our DOM, we can refer
// directly to functions declared on that fragment.
context.fragments.todos.functions.addTodoItem(name)
}
})
```

:::
::: code-group-item dashboard/todos.ts
```typescript
import { ContextApi, ServiceTopic, expose } from '@collage/core'
const context = await expose({
services: {
todos: {
topics: ['active']
}
},
functions: {
addTodoItem
}
}) as ContextApi & { topics: MyTopics }


// Declare the custom topics we want to use in our app
type MyTopics = {
todos: {
active: ServiceTopic
}
}


function publishActiveTodos() {
// The topic api provides `publish` and `subscribe` methods to each defined
// topic.
// We use that to publish an array of all todo items that are not already
// checked off.
context.topics.todos.active.publish(
([...document.querySelectorAll('[type=checkbox]')] as HTMLInputElement[])
.filter(({checked}) => !checked)
.map(input => input.closest('label'))
.map(label => label?.textContent)
)
}

function addTodoItem(text: string) {
if (!text) return

const item = document.createElement('li')
item.innerHTML = `<label><input type="checkbox">${text}</label>`
document.querySelector('#add-todo')?.before(item)

// re-publish the active items, since they have changed
publishActiveTodos()
}

document.addEventListener('submit', event => {
event.preventDefault()
const input = document.querySelector('[name=new-todo]') as HTMLInputElement
if (input) {
addTodoItem(input.value)
input.value = ''
}
})

// re-publish the active items, since they have changed
document.addEventListener('change', publishActiveTodos)
```
:::
::::
4 changes: 2 additions & 2 deletions src/core/topics-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ServiceTopicsAPI } from './service-topics/model';
import { ServiceTopicsAPI, ServiceTopic } from './service-topics/model';
import { SimpleTopicsAPI } from './simple-topics/model';

export type { SimpleTopicsAPI, ServiceTopicsAPI };
export type { SimpleTopicsAPI, ServiceTopicsAPI, ServiceTopic };
12 changes: 7 additions & 5 deletions src/core/topics-plugin/service-topics/model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export type ServiceTopic = {
publish: (message: unknown) => void,
subscribe: (callback: (message: unknown) => unknown) => string,
unsubscribe: (subscriptionId: string) => void,
}

export type ServiceTopicsAPI = {
[topic: string]: {
publish: (message: unknown) => void,
subscribe: (callback: (message: unknown) => unknown) => string,
unsubscribe: (subscriptionId: string) => void,
}
[topic: string]: ServiceTopic;
}
3 changes: 2 additions & 1 deletion src/lib/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { FrontendDescription, ContextApi } from '../../types';
import { SimpleTopicsAPI, ServiceTopicsAPI } from '../../core/topics-plugin';
import { SimpleTopicsAPI, ServiceTopicsAPI, ServiceTopic } from '../../core/topics-plugin';

export type {
FrontendDescription,
ContextApi,
SimpleTopicsAPI,
ServiceTopicsAPI,
ServiceTopic,
};

0 comments on commit 77617a7

Please sign in to comment.