framework/server
back の宣言 ── 生成器が app の src/server.gleam の const を読み、src/gen/registry.mjs /
http_runtime.mjs / shell.mjs / queue_runtime.mjs / cron_runtime.mjs を書く(0.11.1、WGy)。
置く const は下のとおり。どれも無くてよい(無ければ空の表)。
pub const routes: List(Route)── Service の (method, path) の上書き。導出規則(entry の prefix と Entity / Args の型)と同じ行は書かない。公開の URL(REST v1、鍵の発行)は導出に寄せず、ここで固定するpub const aliases: List(Alias)── 同じ Service(または attached の口)の 2 本目の口(REST v1 の別名)pub const attached: List(Attached)── Service でない HTTP の口(session・blob・media・socket など)。 面のapi.gleamのattached表も、ここから書くpub const cron: List(Cron)── 式と、その式で回す仕事pub const durable_objects: List(DurableObject)── class 名と、実装を持つ ★ の adapterpub const hooks: List(Hook)── 宣言から導けない業務の行の口。生成物が import する ★ は、ここに名を 書いたものだけpub const reads: List(ManualRead)── 手書きの SQL で引く読み。生成器は型付きの口と runtime の振り分けを書き、 SQL と行の写し(hook)は ★pub const roots: List(RootShape)── root の導出(allow の Entity と Args の key の型)と違う Service の rootpub const storage: List(Storage)── Entity の器と列の写像。導出(Neon のapp.<module>、Property 名 = 列名、payload の無い sum は text、record と List は jsonb)と違う Entity の Property だけを書くpub const attached_roles: List(AttachedRole)── 機関を framework が持つ attached の口の役(session・ browser の申告・path の残りを取る口)。framework の JS は app の口の名を知らず、ここから受けるpub const browser: BrowserCookie── 成人の申告を焼く browser の署名 cookie の名・鍵の binding・期間pub const subject_free: List(String)── 入口の主体の集合(Subjects([..]))に session の主体が入っていなくても 通す Service の名。主体を切り替える前に読む口(店の面の/switchが並べる、party の持つ店の主体)だけを書く (gate-1 r2。framework の JS は Service の名を知らない)
framework の JS が app に求めるもの(npm の依存と db/queries/framework/** の SQL)は README を見よ。
Service は名(module の名、article_publish)で指す ── Service の値は型引数が Service ごとに違い、
1 つの List に並ばないため。名が Service に無ければ生成器が exit 4 で名指しする。
path の変数は :name(registry の綴り)。
Types
pub type Alias {
Alias(
name: String,
service: String,
method: Method,
path: String,
credential: Credential,
external_id: Bool,
)
AttachedAlias(
name: String,
attached: String,
method: Method,
path: String,
credential: Credential,
who: Who,
)
}
Constructors
-
Alias( name: String, service: String, method: Method, path: String, credential: Credential, external_id: Bool, )Service の 2 本目の口。
external_id: Trueは path の:external_idを店の外部 id として 引き直し、Args のidに入れる。 -
AttachedAlias( name: String, attached: String, method: Method, path: String, credential: Credential, who: Who, )attached の口の 2 本目。
attached の口のうち、機関を framework の JS(framework/server/http.mjs)が持つものの役(WGy r4)。
framework は app の口の名を知らない ── どの attached の名がどの役かを app がここで渡す
(pub const attached_roles: List(AttachedRole))。1 つの口に役を 2 つ以上書いてよい。
名が attached に無ければ生成器が exit 4 で名指しする。
pub type AttachedRole {
DeclareBrowser(attached: String)
ReadSession(attached: String)
SwitchSubject(attached: String)
TailPath(attached: String)
NeedsBrowser(attached: String)
}
Constructors
-
DeclareBrowser(attached: String)成人の申告を browser の署名 cookie に焼く(
browserの宣言が要る)。行はframework/browserの SQL -
ReadSession(attached: String)session の中身(party・主体・同意・browser の申告)を返す
-
SwitchSubject(attached: String)session の主体を切り替える。行は
framework/session_subject_staffの SQL -
TailPath(attached: String)path の最後の穴(
:key)が/を含む残り全部を取り、GET と HEAD で受ける -
NeedsBrowser(attached: String)署名した browser の申告が無ければ 403(
adult_declaration_missing)で閉じる
成人の申告を焼く browser の署名 cookie(WGy r4、pub const browser: BrowserCookie)。cookie は cookie の名、
key_binding は HMAC の鍵を持つ env の binding(.get() で文字列を返す Secret Store)、claim は payload で
申告の時刻を持つ欄の名、max_age_days は cookie の Max-Age と申告の有効期間。宣言が無ければ browser の
申告は常に無い(DeclareBrowser の口は書けない)。
pub type BrowserCookie {
BrowserCookie(
cookie: String,
key_binding: String,
claim: String,
max_age_days: Int,
)
}
Constructors
-
BrowserCookie( cookie: String, key_binding: String, claim: String, max_age_days: Int, )
口が受ける媒体。entry の Credential と同じ 2 値(ApiKey の per_minute は entry が持つ)。
pub type Credential {
Session
ApiKey
}
Constructors
-
Session -
ApiKey
pub type DurableObject {
DurableObject(
class: String,
module: String,
adapter: String,
methods: List(String),
)
}
Constructors
-
DurableObject( class: String, module: String, adapter: String, methods: List(String), )classは wrangler の class 名、moduleはsrc/からの ★ の道(user_do)、adapterは その module が export する class、methodsは DO の RPC として外へ出す method の名。
pub type Hook {
Hook(name: String, module: String)
}
Constructors
-
Hook(name: String, module: String)moduleはsrc/からの ★ の道(hooks)、nameはその module が export する関数の名。
pub type Job {
EachDue(service: String, query: String)
Hooked(service: String, hook: String)
}
Constructors
-
EachDue(service: String, query: String)列挙の読み(
<service>/<query>の SQL、穴は$1= 起動時刻)の行ごとに Service を 1 回ずつ呼ぶ。 行のidを Args の 1 つ目へ入れる。CAS に負けた行は飛ばして次へ。 -
Hooked(service: String, hook: String)hook が Args を作り、Service を 1 回呼ぶ(期間の計算など、宣言から導けない行)。
手書きの SQL(db/queries/<service>/<query>.sql、★)で引く読み(WGy r3)。生成器は
gen/reads/<service>.gleam の型付きの口(<query>(<args>, then:))と runtime の振り分けを書き、
行の写しは hook(hooks に宣言した ★ の関数)が持つ。型は Gleam の綴り(List(course.Course))、
imports はその綴りが要る import の行の中身(entity/course)。引数が 2 つ以上なら口は組で渡す。
pub type ManualRead {
ManualRead(
service: String,
query: String,
args: List(#(String, String)),
returns: String,
imports: List(String),
hook: String,
)
}
Constructors
-
ManualRead( service: String, query: String, args: List(#(String, String)), returns: String, imports: List(String), hook: String, )
pub type Port {
Call(name: String, op: String)
Send(name: String, op: String)
Enqueue(name: String, kind: String)
Fetch(name: String, module: String, js: String, arity: Int)
Pure(name: String, module: String, js: String, arity: Int)
}
Constructors
-
Call(name: String, op: String)framework の operations の
call(Read の境界)。opは operations の口の名 -
Send(name: String, op: String)framework の operations の
call(Write の境界)。通知のように応答を使わない口 -
Enqueue(name: String, kind: String)framework の operations の
enqueue(Write の境界)。kindは Queue の kind -
Fetch(name: String, module: String, js: String, arity: Int)★ の JS の関数(
moduleはsrc/からの道、拡張子無し)。ctx を先頭に取り Promise を返す(Read の境界) -
Pure(name: String, module: String, js: String, arity: Int)★ の JS の純関数
root の形の上書き(WGy r3)。導出は「allow の Entity の key の型が Args に在れば、その Entity の行」。 作る Service(Args の key は新しい行の鍵)や、主体の行を root にする Service はここに書く。
pub type RootShape {
Rootless(service: String)
OwnRoot(service: String)
RootOf(service: String, entity: String)
WithVersion(service: String)
Carried(
service: String,
name: String,
type_: String,
import_: String,
)
QueueParty(service: String, party: String)
}
Constructors
-
Rootless(service: String)root に Entity の行を持たない(
Root(at, seed)) -
OwnRoot(service: String)root を主体(session の subject)の行にする。Entity は allow の Entity
-
RootOf(service: String, entity: String)root を
entity(module 名)の行にする。鍵は Args のid -
WithVersion(service: String)root に行の
version列(楽観ロックの版、Entity のレコードに無い列)をversion: Intで載せる -
Carried( service: String, name: String, type_: String, import_: String, )root に入口が運ぶ値を載せる(
browser= 署名した browser cookie の id)。type_は Gleam の綴り、import_はその綴りが要る import の行の中身 -
QueueParty(service: String, party: String)queue の consumer
service(root の 1 文を持たず、自分を queue で呼ぶ Service の root を借りる)が、 借りた root を session の partypartyとして読む(root の 1 文と verb のpartyの穴・audit の party)。 書かなければ consumer は party 無しで読む(gate-1 r2、framework の JS から主体の名を抜いた)
pub type Route {
Route(service: String, method: Method, path: String)
RouteVia(
service: String,
method: Method,
path: String,
credential: Credential,
)
Internal(service: String)
}
Constructors
-
Route(service: String, method: Method, path: String)導出の (method, path) をこれに替える。媒体は導出どおり(
Sessionの入口)。 -
RouteVia( service: String, method: Method, path: String, credential: Credential, )媒体を明示する口。
ApiKeyなら REST v1 の入口だけが持つ。 -
Internal(service: String)HTTP の口を持たない Service(queue・cron・Service からの呼び出しだけ)。
Entity の器と列の写像(WGy r3、鷹野の裁定)。entity は Entity の module 名(muse_setting_spec)、
property はレコードの欄の名(type_)。生成器は verb の SQL をこの写像で書き、穴の契約
(Property 1 つに穴 1 つ、値は codec の encode)は変えない ── 割る・写すのは SQL の側でする。
pub type Storage {
InObject(entity: String, object: String)
Column(entity: String, property: String, column: String)
Text(
entity: String,
property: String,
values: List(#(String, String)),
)
Split(
entity: String,
property: String,
columns: List(#(String, String)),
)
Array(entity: String, property: String, element: String)
}
Constructors
-
InObject(entity: String, object: String)Entity を Neon でなく Durable Object の SQLite に置く。
objectはdurable_objectsの class 名。 生成器はこの Entity の PG 向けの SQL(verb・読み)を出さず、器の ★ adapter が持つ -
Column(entity: String, property: String, column: String)Property の列名を替える(
type_→type、default→default_value) -
Text( entity: String, property: String, values: List(#(String, String)), )payload の無い構成子だけの sum を text 1 列で持つ。
valuesは (構成子, 列の値)。 列名は Property 名(Columnがあればその列) -
Split( entity: String, property: String, columns: List(#(String, String)), )record(または
Option(record))の Property を複数の列に割る。columnsは (record の欄, 列) -
Array(entity: String, property: String, element: String)List(<値型>)を PG の配列で持つ。elementは要素の SQL の型(uuid)