Skip to content

Commit

Permalink
feat: Initial version. #1484
Browse files Browse the repository at this point in the history
  • Loading branch information
mturoci committed Aug 10, 2023
1 parent 5ab72b7 commit 76fe2e1
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 6 deletions.
4 changes: 3 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ var (
// BootMsg represents the initial message sent to an app when a client first connects to it.
type BootMsg struct {
Data struct {
Hash string `json:"#,omitempty"` // location hash
Hash string `json:"#,omitempty"` // location hash
SubmissionName string `json:"__wave_submission_name__,omitempty"` // mark the cause of the serve invocation
} `json:"data"`
Headers http.Header `json:"headers"` // forwarded headers
}
Expand Down Expand Up @@ -164,6 +165,7 @@ func (c *Client) listen() {

if len(m.data) > 0 { // location hash
boot.Data.Hash = string(m.data)
boot.Data.SubmissionName = "#"
}

body, err := json.Marshal(boot)
Expand Down
2 changes: 1 addition & 1 deletion py/h2o_wave/h2o_wave/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"""
from .core import Site, AsyncSite, site, Page, Ref, data, pack, Expando, expando_to_dict, clone_expando, copy_expando
from .server import listen, Q, app, main
from .routing import on, handle_on
from .routing import on, handle_on, run_on
from .db import connect, WaveDBConnection, WaveDB, WaveDBError
from .types import *
from .test import cypress, Cypress
Expand Down
47 changes: 47 additions & 0 deletions py/h2o_wave/h2o_wave/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,53 @@ async def _match_predicate(predicate: Callable, func: Callable, arity: int, q: Q
return False


async def run_on(q: Q) -> bool:
"""
Handle the query using a query handler (a function annotated with `@on()`).
Args:
q: The query context.
Returns:
True if a matching query handler was found and invoked, else False.
"""
submitted = str(q.args['__wave_submission_name__'])

# Event handlers.
event = q.events[submitted]
for entry in _event_handlers.get(submitted, []):
event_type, predicate, func, arity = entry
if event_type in event:
arg_value = event[event_type]
if await _match_predicate(predicate, func, arity, q, arg_value):
return True

# Hash handlers.
if submitted == '#':
for rx, conv, func, arity in _path_handlers:
match = rx.match(q.args[submitted])
if match:
params = match.groupdict()
for key, value in params.items():
params[key] = conv[key].convert(value)
if len(params):
if arity <= 1:
await _invoke_handler(func, arity, q, None)
else:
await func(q, **params)
else:
await _invoke_handler(func, arity, q, None)
return True

# Arg handlers.
for entry in _arg_handlers.get(submitted, []):
predicate, func, arity = entry
if await _match_predicate(predicate, func, arity, q, q.args[submitted]):
return True

return False


async def handle_on(q: Q) -> bool:
"""
Handle the query using a query handler (a function annotated with `@on()`).
Expand Down
6 changes: 5 additions & 1 deletion ui/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ const
}),
App = bond(() => {
const
onHashChanged = () => wave.push(),
onHashChanged = () => {
const h = window.location.hash
if (h?.length > 1) wave.args['#'] = h.substring(1)
wave.push()
},
onMdLinkClick = ({ detail }: any) => {
wave.args[detail] = true
wave.push()
Expand Down
16 changes: 13 additions & 3 deletions ui/src/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ export function bond<TProps, TState extends Renderable>(ctor: (props: TProps) =>
}
}

let _wave: Wave | null = null
let
_wave: Wave | null = null,
submissionName = ''

const
args: Rec = {},
Expand Down Expand Up @@ -149,21 +151,28 @@ export const

// Unconditionally set location hash so that the app doesn't have to track changes.
const h = window.location.hash
if (h?.length > 1) args['#'] = h.substr(1)
if (h?.length > 1) args['#'] = h.substring(1)
if (submissionName) args['__wave_submission_name__'] = submissionName

const d: Dict<any> = { ...args } // shallow clone
clearRec(args) // clear
_wave.push(d) // push clone
busyB(true)
argsB(d)
submissionName = ''
},
wave = { // Public API
baseURL,
socketURL,
uploadURL,
initURL,
loginURL,
args,
args: new Proxy(args, {
set(target, key, value) {
submissionName = key.toString()
return Reflect.set(target, key, value)
},
}),
debounce,
throttle,
push,
Expand All @@ -178,6 +187,7 @@ export const
event[name] = data
events[source] = event
args[''] = events // '' is special-cased in clients
submissionName = source
push()
}
};
Expand Down

0 comments on commit 76fe2e1

Please sign in to comment.