DrSensor / nusa

incremental runtime that bring both simplicity and power into webdev (buildless, cross-language, data-driven)
MIT License
4 stars 0 forks source link

Data fetching++ #72

Open DrSensor opened 1 year ago

DrSensor commented 1 year ago

Inspired from htmx but use any arbitrary data format for data binding instead of swapping html.

Note When linking JSON data, the format is determined by http header N-Data-Format with the value is either column or row.

<link -let=str href=./string.js>
.
.
<table -let=tab -load.data=table.csv
-keyfmt=str.kebabcase
@scrollbottom=$reload
$reload.param="page=[@scrollbottom.count]
count=[tab.#initialRow]"
$reload.header="
X-Table-From: profile
X-Table-Select: name, location, bod
">
<tr>
<th -map=str.lastWord
-filter=str.isAlphabet>Name</th>
<th>Location</th>
<th -key=bod>Birth Day</th>
</tr>
<!-- default template and action-target pair
either template or attributes can be omitted -->
<template $reload.action=clone
$reload.action.target.self>
<tr>
<td ~ #text=tab.name></td>
<td ~ #text=tab.location></td>
<td ~ #text=tab.bod></td>
</tr>
</template>
</table>

Note For single data (not table), the value of N-Data-Format is either record or entry.


<label id=item -let=my -load.data=/data
-header="
{GET} Accept: text/json; charset=utf-8
{POST PUT PATCH}
Content-Type: text/json

{*} X-Request-From: [my.name]"

$send.method=PUT $send-request.param="user=[my.name~>str.snakecase]"

$update.method=PATCH $update.param="formatkey=snakecase"

$reload.method=GET -load.method=GET>

name: <input type=text ~ .value="my.name<~>str.capitalize">

<button disabled ~ !disabled $reload=#item @click=debounce:$reload> Reload

<button disabled ~ !disabled $update=#item @click=$update $update.toggle=disabled> Update

<button disabled ~ !disabled $send=#item -request.0=/notify/user -request.1=/notify/group @click="$send $send-request"> Force Update

> **Note**
> Those paired http methods are the default, everything else is custom

> **Note**
> Sometimes `N-Data-Format` can be inferred based on the data shape itself.

Use `<link>` to handle multiple data.
```html
<ul id=panel -load.data -keyfmt=str.kebabcase>
  <link -let=my type=text/json href=/user -ignore="$reload $send">
  <link -let=my type=text/json href=/resource -ignore="[POST] [PUT]">

  <li>Name<input type=text ~ @change=set:my.name>
  <li>Project<input type=text ~ @change=set:my.repo>
</ul>

<button disabled ~ !disabled
  $reload=#panel>
  Reload [GET] multiple data
</button>

<button disabled ~ !disabled 
  $update=#panel
  $update.toggle=[#self.disabled]>
  Update [POST] multiple data
</button>

<button disabled ~ !disabled
  $send=#item
  -request=/notify/user>
  Force Update [POST] multiple data
</button>

In that example, each <link> is a record. However, it also applicable on table too (i.e via html attribute type=text/csv or response header N-Data-Format: column) which need <template> to render each <li>.

DrSensor commented 1 year ago

I'm thinking to support swapping html too but it may require morphdom. Maybe this case should be handled by <go-to> or <morph-to> element #12 rather than specifying it as additional attributes 🤔


EDIT: Apparently there is separate issue for that 😅 #29

DrSensor commented 1 year ago

TODO:

DrSensor commented 1 year ago

Most likely gonna change:

Hopefully this make the attribute name reflect the microdata model pattern 🤲

DrSensor commented 1 year ago

About batch request, I think this might work

const form = new FormData()
form.append(uuid, new Blob(
  req_toHTTP1_str(
    new Request(...)).toWellFormed(),
  { type: "application/http" }
))

fetch(url, {
  method: "POST",
  headers,
  cache: "no-store",
  body: form,
  signal: abort.signal,
})
DrSensor commented 1 year ago

Although this use GAS (Google Apps Script), not Web API, at least it give a general idea how to do batch request https://github.com/tanaikech/BatchRequest/blob/master/BatchRequests.js#L234,