Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bootstrap chat global state/logic #1

Merged
merged 1 commit into from
Jul 3, 2024
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
26 changes: 26 additions & 0 deletions apps/storybook/stories/orama-chat.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { StoryObj, Meta } from '@storybook/web-components'

const meta: Meta = {
title: 'Orama Chat',
component: 'orama-chat'
}

export default meta
type Story = StoryObj

const Template = (props) => {
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const element = document.createElement('orama-chat') as any

for (const key of Object.keys(props)) {
element[key] = props[key]
}

return element
}

// More on writing stories with args: https://storybook.js.org/docs/html/writing-stories/args
export const Primary: Story = {
render: Template,
args: {}
}
6 changes: 2 additions & 4 deletions apps/storybook/stories/search-box.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import type { StoryObj, Meta } from '@storybook/web-components'

const meta: Meta = {
title: 'Public/SearchBox',
component: 'search-box',
title: 'SearchBox',
component: 'search-box'
}

export default meta
type Story = StoryObj

const Template = (props) => {
console.log(props)

// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const element = document.createElement('search-box') as any
element.theme = props.theme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ import { ProxyCmp } from './angular-component-lib/utils';
import { Components } from 'orama-ui';


@ProxyCmp({
})
@Component({
selector: 'orama-chat',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: [],
})
export class OramaChat {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}


export declare interface OramaChat extends Components.OramaChat {}


@ProxyCmp({
})
@Component({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as d from './components';

export const DIRECTIVES = [
d.OramaChat,
d.OramaP,
d.SearchBox
];
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import type { JSX } from 'orama-ui';



export const OramaChat = /*@__PURE__*/createReactComponent<JSX.OramaChat, HTMLOramaChatElement>('orama-chat');
export const OramaP = /*@__PURE__*/createReactComponent<JSX.OramaP, HTMLOramaPElement>('orama-p');
export const SearchBox = /*@__PURE__*/createReactComponent<JSX.SearchBox, HTMLSearchBoxElement>('search-box');
3 changes: 3 additions & 0 deletions packages/ui-stencil-vue/lib/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import type { JSX } from 'orama-ui';



export const OramaChat = /*@__PURE__*/ defineContainer<JSX.OramaChat>('orama-chat', undefined);


export const OramaP = /*@__PURE__*/ defineContainer<JSX.OramaP>('orama-p', undefined);


Expand Down
91 changes: 45 additions & 46 deletions packages/ui-stencil/package.json
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
{
"name": "ui-stencil",
"version": "0.0.1",
"description": "Stencil Component Starter",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/stencil-component-starter.git"
},
"main": "dist/index.cjs.js",
"module": "dist/index.js",
"files": [
"dist/",
"loader/"
],
"scripts": {
"build": "stencil build --docs",
"clean": "rm -rf node_modules .turbo dist .stencil loader www",
"dev": "stencil build --watch",
"generate": "stencil generate",
"start": "stencil build --dev --watch --serve",
"test": "stencil test --spec --e2e",
"test.watch": "stencil test --spec --e2e --watchAll"
},
"types": "dist/types/index.d.ts",
"dependencies": {
"@stencil/core": "^4.19.0",
"@stencil/store": "^2.0.16"
},
"devDependencies": {
"@stencil-community/postcss": "^2.2.0",
"@stencil/angular-output-target": "^0.8.4",
"@stencil/react-output-target": "^0.5.3",
"@stencil/sass": "^3.0.12",
"@stencil/vue-output-target": "^0.8.8",
"@types/jest": "^29.5.12",
"@types/node": "^20.14.9",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"puppeteer": "^22.12.1",
"sass-loader": "^14.2.1"
},
"collection": "dist/collection/collection-manifest.json",
"collection:main": "dist/collection/index.js",
"es2015": "dist/esm/index.mjs",
"es2017": "dist/esm/index.mjs",
"unpkg": "dist/ui-stencil/ui-stencil.esm.js"
"name": "ui-stencil",
"version": "0.0.1",
"description": "Stencil Component Starter",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/stencil-component-starter.git"
},
"main": "dist/index.cjs.js",
"module": "dist/index.js",
"files": ["dist/", "loader/"],
"scripts": {
"build": "stencil build --docs",
"clean": "rm -rf node_modules .turbo dist .stencil loader www",
"dev": "stencil build --watch",
"generate": "stencil generate",
"start": "stencil build --dev --watch --serve",
"test": "stencil test --spec --e2e",
"test.watch": "stencil test --spec --e2e --watchAll"
},
"types": "dist/types/index.d.ts",
"dependencies": {
"@oramacloud/client": "1.3.2",
"@stencil/core": "^4.19.0",
"@stencil/store": "^2.0.16",
"sse.js": "^2.5.0"
},
"devDependencies": {
"@stencil/store": "^2.0.16",
"@stencil/angular-output-target": "^0.8.4",
"@stencil/react-output-target": "^0.5.3",
"@stencil/vue-output-target": "^0.8.8",
"@stencil/sass": "^3.0.12",
"@types/jest": "^29.5.12",
"@types/node": "^20.14.9",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"puppeteer": "^22.12.1",
"sass-loader": "^14.2.1"
},
"collection": "dist/collection/collection-manifest.json",
"collection:main": "dist/collection/index.js",
"es2015": "dist/esm/index.mjs",
"es2017": "dist/esm/index.mjs",
"unpkg": "dist/ui-stencil/ui-stencil.esm.js"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder more for me actually :) : when I save json files, it automatically formats with 4 spaces, have to check the vscode settings

}
13 changes: 13 additions & 0 deletions packages/ui-stencil/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
export namespace Components {
interface OramaChat {
}
interface OramaP {
}
interface SearchBox {
Expand All @@ -14,6 +16,12 @@ export namespace Components {
}
}
declare global {
interface HTMLOramaChatElement extends Components.OramaChat, HTMLStencilElement {
}
var HTMLOramaChatElement: {
prototype: HTMLOramaChatElement;
new (): HTMLOramaChatElement;
};
interface HTMLOramaPElement extends Components.OramaP, HTMLStencilElement {
}
var HTMLOramaPElement: {
Expand All @@ -27,18 +35,22 @@ declare global {
new (): HTMLSearchBoxElement;
};
interface HTMLElementTagNameMap {
"orama-chat": HTMLOramaChatElement;
"orama-p": HTMLOramaPElement;
"search-box": HTMLSearchBoxElement;
}
}
declare namespace LocalJSX {
interface OramaChat {
}
interface OramaP {
}
interface SearchBox {
"color"?: 'dark' | 'light' | 'system';
"themeConfig"?: { colors: { light: { primaryColor: string }; dark: { primaryColor: string } } };
}
interface IntrinsicElements {
"orama-chat": OramaChat;
"orama-p": OramaP;
"search-box": SearchBox;
}
Expand All @@ -47,6 +59,7 @@ export { LocalJSX as JSX };
declare module "@stencil/core" {
export namespace JSX {
interface IntrinsicElements {
"orama-chat": LocalJSX.OramaChat & JSXBase.HTMLAttributes<HTMLOramaChatElement>;
"orama-p": LocalJSX.OramaP & JSXBase.HTMLAttributes<HTMLOramaPElement>;
"search-box": LocalJSX.SearchBox & JSXBase.HTMLAttributes<HTMLSearchBoxElement>;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-stencil/src/components/SearchBox/SearchBox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, Host, Prop, h } from '@stencil/core'
import { sassVariables } from '../../config/colors';
import { sassVariables } from '../../config/colors'

@Component({
tag: 'search-box',
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-stencil/src/components/orama-chat/orama-chat.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:host
display: block
70 changes: 70 additions & 0 deletions packages/ui-stencil/src/components/orama-chat/orama-chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Component, Host, State, h } from '@stencil/core'
import { OramaClient } from '@oramacloud/client'
import { ChatService } from '../../services/ChatService'
import { chatContext } from '../../context/chatContext'

@Component({
tag: 'orama-chat',
styleUrl: 'orama-chat.sass',
shadow: true
})
export class OramaChat {
@State() inputValue = ''

private chatService: ChatService

componentWillLoad() {
// TODO: Should not be hardcoded
const oramaClient = new OramaClient({
api_key: '6kHcoevr3zkbBmC2hHqlcNQrOgejS4ds',
endpoint: 'https://cloud.orama.run/v1/indexes/orama-docs-pgjign'
})

this.chatService = new ChatService(oramaClient)
}

handleSubmit = (e: Event) => {
e.preventDefault()

if (!this.chatService) {
throw new Error('Char Service is not initialized')
}

this.chatService.sendQuestion(this.inputValue)
this.inputValue = ''
}

render() {
return (
<Host>
<form onSubmit={this.handleSubmit}>
<div>Is loading: {String(chatContext.isLoading)}</div>
<div>Is error: {String(chatContext.error)}</div>
<div style={{ display: 'flex' }}>
<input
autofocus
style={{ width: '100%' }}
type="text"
value={this.inputValue}
onInput={(e: Event) => (this.inputValue = (e.target as HTMLInputElement).value)}
/>
<button type="submit" onClick={this.handleSubmit}>
Ask
</button>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
{chatContext.messages.map((message, index) => (
// biome-ignore lint/suspicious/noArrayIndexKey: There is not other key available form SDK right now
<div key={index} style={{ display: 'flex', flexDirection: 'column', gap: '32px' }}>
{/* TODO: We still do not have sources */}
<div>
<span>Content: </span> {message.content}
</div>
</div>
))}
</div>
</form>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the ds components will be available, we will replace with the components

</Host>
)
}
}
10 changes: 10 additions & 0 deletions packages/ui-stencil/src/components/orama-chat/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# orama-chat



<!-- Auto Generated Below -->


----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
23 changes: 23 additions & 0 deletions packages/ui-stencil/src/context/chatContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createStore } from '@stencil/store'

// TODO: Seems like there is no message type being exported from orama-client rn
// export type TChatMessageBlock = {
// type: 'text' | 'component' | 'sources'
// received?: boolean
// content: string
// }

export type TChatMessage = {
role: 'user' | 'assistant'
content: string
// messageBlocks: TChatMessageBlock[]
}

const { state: chatContext } = createStore({
messages: [] as TChatMessage[],
isLoading: false,
// TODO: Evaluate if we need to have a error object/string instead of just a boolean
error: false
})

export { chatContext }
18 changes: 18 additions & 0 deletions packages/ui-stencil/src/context/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createStore } from '@stencil/store'

const { state } = createStore({
open: false,
count: 0,
facets: null as Record<
string,
{
count: number
values: Record<string, number>
}
> | null,
hits: [],
term: '',
highlightedIndex: -1
})

export default state
5 changes: 5 additions & 0 deletions packages/ui-stencil/src/erros/OramaClientNotInitialized.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class OramaClientNotInitializedError extends Error {
constructor() {
super('Orama Client is not initialized')
}
}
Loading
Loading