Skip to content

Commit

Permalink
Merge pull request #66 from eyra/locale
Browse files Browse the repository at this point in the history
Added locale as parameter, renamed Storage to Bridge, and add CommandSystemExit
  • Loading branch information
trbKnl authored Dec 8, 2023
2 parents 46f27fa + c9c192d commit 682e62b
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 82 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ Port uses the following data model (also see: [src/framework/types](src/framewor
| ProcessingEngine | Responsible for processing donation flows |
| VisualizationEngine | Responsible for presenting the UI and accepting user input |
| CommandHandler | Decoupling of ProcessingEngine and VisualizationEngine |
| Storage | Callback interface for Storage Commands (e.g. Donation) |
| Bridge | Callback interface for Bridge Commands (e.g. Donation) |

- [Pages](src/framework/types/pages.ts)

Expand Down Expand Up @@ -345,7 +345,7 @@ See: [src/framework/processing/py/port](src/framework/processing/py/port)

- [API](src/framework/processing/py/port/api)

- [commands.py](src/framework/processing/py/port/api/commands.py): Defines commands, pages and prompts that are used to communicate from the Python script to the `VisualisationEngine` and `Storage`.
- [commands.py](src/framework/processing/py/port/api/commands.py): Defines commands, pages and prompts that are used to communicate from the Python script to the `VisualisationEngine` and `Bridge`.
- [props.py](src/framework/processing/py/port/api/commands.py): Defines property objects for pages and prompts

## Code instructions
Expand Down Expand Up @@ -542,15 +542,15 @@ Change implementation of [assembly.ts](src/framework/assembly.ts) to support you
```Typescript
import MyEngine from './visualisation/my/engine'
import WorkerProcessingEngine from './processing/worker_engine'
import { VisualisationEngine, ProcessingEngine, Storage } from './types/modules'
import { VisualisationEngine, ProcessingEngine, Bridge } from './types/modules'
import CommandRouter from './command_router'

export default class Assembly {
visualisationEngine: VisualisationEngine
processingEngine: ProcessingEngine
router: CommandRouter

constructor (worker: Worker, system: Storage) {
constructor (worker: Worker, bridge: Bridge) {
const sessionId = String(Date.now())
this.visualisationEngine = new MyEngine()
this.router = new CommandRouter(system, this.visualisationEngine)
Expand Down
Binary file modified public/port-0.0.0-py3-none-any.whl
Binary file not shown.
22 changes: 22 additions & 0 deletions src/fake_bridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { CommandSystem, CommandSystemDonate, CommandSystemExit, isCommandSystemDonate, isCommandSystemExit } from './framework/types/commands'
import { Bridge } from './framework/types/modules'

export default class FakeBridge implements Bridge {
send (command: CommandSystem): void {
if (isCommandSystemDonate(command)) {
this.handleDonation(command)
} else if (isCommandSystemExit(command)) {
this.handleExit(command)
} else {
console.log('[FakeBridge] received unknown command: ' + JSON.stringify(command))
}
}

handleDonation (command: CommandSystemDonate): void {
console.log(`[FakeBridge] received donation: ${command.key}=${command.json_string}`)
}

handleExit (command: CommandSystemExit): void {
console.log(`[FakeBridge] received exit: ${command.code}=${command.info}`)
}
}
16 changes: 0 additions & 16 deletions src/fake_storage.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/framework/assembly.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import ReactEngine from './visualisation/react/engine'
import ReactFactory from './visualisation/react/factory'
import WorkerProcessingEngine from './processing/worker_engine'
import { VisualisationEngine, ProcessingEngine, Storage } from './types/modules'
import { VisualisationEngine, ProcessingEngine, Bridge } from './types/modules'
import CommandRouter from './command_router'

export default class Assembly {
visualisationEngine: VisualisationEngine
processingEngine: ProcessingEngine
router: CommandRouter

constructor (worker: Worker, system: Storage) {
constructor (worker: Worker, bridge: Bridge) {
const sessionId = String(Date.now())
this.visualisationEngine = new ReactEngine(new ReactFactory())
this.router = new CommandRouter(system, this.visualisationEngine)
this.router = new CommandRouter(bridge, this.visualisationEngine)
this.processingEngine = new WorkerProcessingEngine(sessionId, worker, this.router)
}
}
10 changes: 5 additions & 5 deletions src/framework/command_router.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Command, Response, isCommandSystem, isCommandUI, CommandUI, CommandSystem } from './types/commands'
import { CommandHandler, Storage, VisualisationEngine } from './types/modules'
import { CommandHandler, Bridge, VisualisationEngine } from './types/modules'

export default class CommandRouter implements CommandHandler {
system: Storage
bridge: Bridge
visualisationEngine: VisualisationEngine

constructor (system: Storage, visualisationEngine: VisualisationEngine) {
this.system = system
constructor (bridge: Bridge, visualisationEngine: VisualisationEngine) {
this.bridge = bridge
this.visualisationEngine = visualisationEngine
}

Expand All @@ -23,7 +23,7 @@ export default class CommandRouter implements CommandHandler {
}

onCommandSystem (command: CommandSystem, resolve: (response: Response) => void): void {
this.system.send(command)
this.bridge.send(command)
resolve({ __type__: 'Response', command, payload: { __type__: 'PayloadVoid', value: undefined } })
}

Expand Down
Binary file modified src/framework/processing/py/dist/port-0.0.0-py3-none-any.whl
Binary file not shown.
15 changes: 15 additions & 0 deletions src/framework/processing/py/port/api/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ def toDict(self):
dict["key"] = self.key
dict["json_string"] = self.json_string
return dict


class CommandSystemExit:
__slots__ = "code", "info"

def __init__(self, code, info):
self.code = code
self.info = info

def toDict(self):
dict = {}
dict["__type__"] = "CommandSystemExit"
dict["code"] = self.code
dict["info"] = self.info
return dict
6 changes: 5 additions & 1 deletion src/framework/processing/py/port/script.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import port.api.props as props
from port.api.commands import (CommandSystemDonate, CommandUIRender)
from port.api.commands import (CommandSystemDonate, CommandSystemExit, CommandUIRender)

import pandas as pd
import zipfile
Expand Down Expand Up @@ -58,6 +58,7 @@ def process(sessionId):
meta_data.append(("debug", f"{platform}: donate consent data"))
yield donate(f"{sessionId}-{platform}", consent_result.value)

yield exit(0, "Success")
yield render_end_page()


Expand Down Expand Up @@ -141,3 +142,6 @@ def prompt_consent(id, data, meta_data):

def donate(key, json_string):
return CommandSystemDonate(key, json_string)

def exit(code, info):
return CommandSystemExit(code, info)
14 changes: 12 additions & 2 deletions src/framework/types/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ export function isCommand (arg: any): arg is Command {
}

export type CommandSystem =
CommandSystemDonate
CommandSystemDonate |
CommandSystemExit

export function isCommandSystem (arg: any): arg is CommandSystem {
return isCommandSystemDonate(arg)
return isCommandSystemDonate(arg) || isCommandSystemExit(arg)
}

export type CommandUI =
Expand All @@ -104,6 +105,15 @@ export function isCommandSystemDonate (arg: any): arg is CommandSystemDonate {
return isInstanceOf<CommandSystemDonate>(arg, 'CommandSystemDonate', ['key', 'json_string'])
}

export interface CommandSystemExit {
__type__: 'CommandSystemExit'
code: number
info: string
}
export function isCommandSystemExit (arg: any): arg is CommandSystemExit {
return isInstanceOf<CommandSystemExit>(arg, 'CommandSystemExit', ['code', 'info'])
}

export interface CommandUIRender {
__type__: 'CommandUIRender'
page: PropsUIPage
Expand Down
2 changes: 1 addition & 1 deletion src/framework/types/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface VisualisationEngine {
terminate: () => void
}

export interface Storage {
export interface Bridge {
send: (command: CommandSystem) => void
}

Expand Down
29 changes: 18 additions & 11 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import './fonts.css'
import './framework/styles.css'
import Assembly from './framework/assembly'
import { Storage } from './framework/types/modules'
import LiveStorage from './live_storage'
import FakeStorage from './fake_storage'
import { Bridge } from './framework/types/modules'
import LiveBridge from './live_bridge'
import FakeBridge from './fake_bridge'

const rootElement = document.getElementById('root') as HTMLElement

const locale = 'en'
const workerFile = new URL('./framework/processing/py_worker.js', import.meta.url)
const worker = new Worker(workerFile)

let assembly: Assembly

const run = (system: Storage): void => {
assembly = new Assembly(worker, system)
const run = (bridge: Bridge, locale: string): void => {
assembly = new Assembly(worker, bridge)
assembly.visualisationEngine.start(rootElement, locale)
assembly.processingEngine.start()
}

if (process.env.REACT_APP_BUILD!=='standalone' && process.env.NODE_ENV === 'production') {
if (process.env.REACT_APP_BUILD !== 'standalone' && process.env.NODE_ENV === 'production') {
// Setup embedded mode (requires to be embedded in iFrame)
console.log('Initializing storage system')
LiveStorage.create(window, run)
console.log('Initializing bridge system')
LiveBridge.create(window, run)
} else {
// Setup local development mode
console.log('Running with fake storage')
run(new FakeStorage())
console.log('Running with fake bridge')
run(new FakeBridge(), 'en')
}

const observer = new ResizeObserver(() => {
const height = window.document.body.scrollHeight;
const action = "resize"
window.parent.postMessage({action, height}, "*")
});

observer.observe(window.document.body);
36 changes: 36 additions & 0 deletions src/live_bridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { CommandSystem, isCommandSystem } from './framework/types/commands'
import { Bridge } from './framework/types/modules'

export default class LiveBridge implements Bridge {
port: MessagePort

constructor (port: MessagePort) {
this.port = port
}

static create (window: Window, callback: (bridge: Bridge, locale: string) => void): void {
window.addEventListener('message', (event) => {
console.log('MESSAGE RECEIVED', event)
// Skip webpack messages
if (event.data.action === 'live-init') {
const bridge = new LiveBridge(event.ports[0])
const locale = event.data.locale
console.log('LOCALE', locale)
callback(bridge, locale)
}
})
}

send (command: CommandSystem): void {
if (isCommandSystem(command)) {
this.port.postMessage(command)
} else {
this.log('error', 'received unknown command', command)
}
}

private log (level: 'info' | 'error', ...message: any[]): void {
const logger = level === 'info' ? console.log : console.error
logger(`[${this.constructor.name}]`, ...message)
}
}
39 changes: 0 additions & 39 deletions src/live_storage.ts

This file was deleted.

0 comments on commit 682e62b

Please sign in to comment.