@gasboost/client 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +386 -0
- package/dist/navigation/AppsScriptIframe.js +5 -4
- package/package.json +21 -1
- package/dist/AppsScriptJob.d.ts +0 -28
- package/dist/AppsScriptJob.js +0 -84
- package/dist/AppsScriptJobQueue.d.ts +0 -14
- package/dist/AppsScriptJobQueue.js +0 -40
- package/dist/AppsScriptJobRunner.d.ts +0 -20
- package/dist/AppsScriptJobRunner.js +0 -93
- package/dist/AppsScriptJobStore.d.ts +0 -7
- package/dist/AppsScriptJobStore.js +0 -9
- package/src/AppsScriptClient.ts +0 -81
- package/src/google.ts +0 -55
- package/src/index.ts +0 -4
- package/src/job/AppsScriptJob.ts +0 -85
- package/src/job/AppsScriptJobQueue.ts +0 -48
- package/src/job/AppsScriptJobRunner.ts +0 -107
- package/src/job/AppsScriptJobStore.ts +0 -16
- package/src/navigation/AppsScriptContainer.ts +0 -47
- package/src/navigation/AppsScriptHistoryPipeline.ts +0 -29
- package/src/navigation/AppsScriptIframe.ts +0 -63
- package/src/navigation/HashProperty.ts +0 -20
- package/src/navigation/NavigationEntry.ts +0 -82
- package/src/navigation/NavigationLocation.ts +0 -54
- package/tests/AppsScriptClient.spec.ts +0 -322
- package/tests/AppsScriptClient.type.spec.ts +0 -52
- package/tests/AppsScriptContainer.spec.ts +0 -502
- package/tests/AppsScriptHistoryPipeline.spec.ts +0 -303
- package/tests/AppsScriptIframe.spec.ts +0 -452
- package/tests/AppsScriptJob.spec.ts +0 -83
- package/tests/AppsScriptJobQueue.spec.ts +0 -125
- package/tests/AppsScriptJobRunner.spec.ts +0 -361
- package/tests/HashProperty.spec.ts +0 -29
- package/tests/NavigationEntry.spec.ts +0 -507
- package/tests/NavigationLocation.spec.ts +0 -189
- package/tests/setup.ts +0 -15
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -6
- package/vitest.config.mts +0 -8
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gasboost
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# @gasboost/client
|
|
2
|
+
|
|
3
|
+
Google Apps Script Web アプリケーション向けの、フレームワーク非依存クライアントライブラリです。
|
|
4
|
+
|
|
5
|
+
`@gasboost/app` で定義した RPC 契約を利用して、フロントエンドから型安全に Google Apps Script のサーバー関数を呼び出せます。
|
|
6
|
+
|
|
7
|
+
また、RPC や任意の非同期処理を Job として管理する仕組みと、Google Apps Script Web アプリケーションの History 同期機能を提供します。
|
|
8
|
+
|
|
9
|
+
## インストール
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @gasboost/client
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
npm:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @gasboost/client
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 型安全な RPC
|
|
22
|
+
|
|
23
|
+
バックエンドで `@gasboost/app` を使って RPC を定義します。
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// backend/main.ts
|
|
27
|
+
|
|
28
|
+
import { AppsScript, type InferAppsScript } from "@gasboost/app";
|
|
29
|
+
|
|
30
|
+
const app = new AppsScript()
|
|
31
|
+
.call("sum", (a: number, b: number) => a + b)
|
|
32
|
+
.call("getUser", async (id: string) => ({
|
|
33
|
+
id,
|
|
34
|
+
name: "Taro",
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
export default app;
|
|
38
|
+
|
|
39
|
+
export type AppType = InferAppsScript<typeof app>;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
フロントエンドでは `AppType` を型として共有します。
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { appsScriptClient } from "@gasboost/client";
|
|
46
|
+
import type { AppType } from "../backend/main";
|
|
47
|
+
|
|
48
|
+
const { client } = appsScriptClient<AppType>();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
これにより、登録された RPC が型安全な関数として利用できます。
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const total = await client.sum(1, 2);
|
|
55
|
+
|
|
56
|
+
const user = await client.getUser("user-1");
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
引数型と戻り値型は `AppType` から推論されます。
|
|
60
|
+
|
|
61
|
+
存在しない RPC や不正な引数は TypeScript 上で検出できます。
|
|
62
|
+
|
|
63
|
+
## RPC Transport
|
|
64
|
+
|
|
65
|
+
RPC は Google Apps Script が提供する `google.script.run` を利用して実行されます。
|
|
66
|
+
|
|
67
|
+
例えば、
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
await client.sum(1, 2);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
は内部的には対応する GAS のサーバー関数を、
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
google.script.run.sum(1, 2)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
のように呼び出します。
|
|
80
|
+
|
|
81
|
+
成功時には `AppsScriptResponse.contents` を JSON として parse し、その結果を返します。
|
|
82
|
+
|
|
83
|
+
GAS 側の失敗は Promise の reject としてそのまま伝播します。
|
|
84
|
+
|
|
85
|
+
## JSON Response
|
|
86
|
+
|
|
87
|
+
RPC のレスポンスは JSON として扱われます。
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const user = await client.getUser("user-1");
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
例えばバックエンドが、
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
{
|
|
97
|
+
id: "user-1",
|
|
98
|
+
name: "Taro",
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
を返した場合、フロントエンドでも同じ構造の object として取得できます。
|
|
103
|
+
|
|
104
|
+
不正な JSON が返された場合は `JSON.parse` のエラーになります。
|
|
105
|
+
|
|
106
|
+
### Date
|
|
107
|
+
|
|
108
|
+
`Date` は JavaScript の `Date` instance には復元されません。
|
|
109
|
+
|
|
110
|
+
例えばバックエンドが、
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
{
|
|
114
|
+
createdAt: new Date("2026-09-04T00:00:00.000Z"),
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
を返した場合、クライアントでは、
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
{
|
|
122
|
+
createdAt: "2026-09-04T00:00:00.000Z",
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
のように string として取得されます。
|
|
127
|
+
|
|
128
|
+
`@gasboost/app` の `InferAppsScript` も、この JSON シリアライズ後の型に合わせて `Date` を `string` として推論します。
|
|
129
|
+
|
|
130
|
+
## appsScriptClient
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const { client, jobs } = appsScriptClient<AppType>();
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`appsScriptClient()` は次の2つを返します。
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
{
|
|
140
|
+
client,
|
|
141
|
+
jobs,
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `client`
|
|
146
|
+
|
|
147
|
+
`AppType` から生成される型安全な RPC client です。
|
|
148
|
+
|
|
149
|
+
### `jobs`
|
|
150
|
+
|
|
151
|
+
RPC と非同期処理の Job を管理します。
|
|
152
|
+
|
|
153
|
+
現在以下の API を提供します。
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
jobs.start(label, execute);
|
|
157
|
+
jobs.cancel(jobId);
|
|
158
|
+
jobs.retry(jobId);
|
|
159
|
+
jobs.subscribe(listener);
|
|
160
|
+
jobs.getSnapshot();
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Job
|
|
164
|
+
|
|
165
|
+
`client` 経由で実行した RPC は自動的に Job として管理されます。
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const { client, jobs } = appsScriptClient<AppType>();
|
|
169
|
+
|
|
170
|
+
const promise = client.getUser("user-1");
|
|
171
|
+
|
|
172
|
+
const snapshot = jobs.getSnapshot();
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
RPC 名が Job の `label` になります。
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
job.label === "getUser";
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Job には一意な `id` が割り当てられます。
|
|
182
|
+
|
|
183
|
+
## Job Status
|
|
184
|
+
|
|
185
|
+
Job は次の状態を持ちます。
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
pending
|
|
189
|
+
running
|
|
190
|
+
success
|
|
191
|
+
failed
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
状態は `status` から取得できます。
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
job.status;
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
個別の判定メソッドも利用できます。
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
job.isPending();
|
|
204
|
+
job.isRunning();
|
|
205
|
+
job.isSuccess();
|
|
206
|
+
job.isFailed();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Job は次の情報も保持します。
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
job.id;
|
|
213
|
+
job.label;
|
|
214
|
+
job.createdAt;
|
|
215
|
+
job.endedAt;
|
|
216
|
+
job.result;
|
|
217
|
+
job.error;
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Job の実行
|
|
221
|
+
|
|
222
|
+
RPC 以外の任意の非同期処理も、同じ Job Queue で管理できます。
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
const { jobs } = appsScriptClient<AppType>();
|
|
226
|
+
|
|
227
|
+
const result = await jobs.start("load-data", async () => {
|
|
228
|
+
return await loadData();
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
`client` から実行された RPC と `jobs.start()` は同じ Queue / Runner を共有します。
|
|
233
|
+
|
|
234
|
+
## 並列実行
|
|
235
|
+
|
|
236
|
+
Job Runner は複数 Job の並列実行に対応しています。
|
|
237
|
+
|
|
238
|
+
現在の最大同時実行数は `30` です。
|
|
239
|
+
|
|
240
|
+
上限を超えた Job は `pending` として Queue に残り、実行中の Job が完了すると順次実行されます。
|
|
241
|
+
|
|
242
|
+
## 成功した Job
|
|
243
|
+
|
|
244
|
+
成功した Job は完了後に Job 一覧から削除されます。
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
jobs.getSnapshot();
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
には、実行中・待機中・失敗した Job が主に残ります。
|
|
251
|
+
|
|
252
|
+
## 失敗した Job
|
|
253
|
+
|
|
254
|
+
失敗した Job は一覧に `failed` 状態で残ります。
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
const failedJob = jobs.getSnapshot().find((job) => job.status === "failed");
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
エラーは `job.error` から取得できます。
|
|
261
|
+
|
|
262
|
+
## Retry
|
|
263
|
+
|
|
264
|
+
失敗した Job は ID を指定して再実行できます。
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
jobs.retry(job.id);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
元の Job は一覧から削除され、同じ `label` と `execute` を利用した新しい Job が Queue に追加されます。
|
|
271
|
+
|
|
272
|
+
そのため、retry 後の Job は新しい ID を持ちます。
|
|
273
|
+
|
|
274
|
+
## Cancel
|
|
275
|
+
|
|
276
|
+
`pending` 状態の Job はキャンセルできます。
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
jobs.cancel(job.id);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
キャンセルされた Job は Queue と Job 一覧から削除され、対応する Promise は `AppsScriptJobCancelledError` で reject されます。
|
|
283
|
+
|
|
284
|
+
すでに `running` になった Job はキャンセルされません。
|
|
285
|
+
|
|
286
|
+
現在の cancel は、実行開始前の Job を Queue から取り除くための機能です。
|
|
287
|
+
|
|
288
|
+
## Job の購読
|
|
289
|
+
|
|
290
|
+
Job 一覧の変更を購読できます。
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
const unsubscribe = jobs.subscribe(() => {
|
|
294
|
+
console.log(jobs.getSnapshot());
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
購読を解除する場合:
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
unsubscribe();
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
`getSnapshot()` は現在の Job 一覧を返します。
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const jobsSnapshot = jobs.getSnapshot();
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
このインターフェースは React の `useSyncExternalStore` から直接利用できる形になっています。
|
|
311
|
+
|
|
312
|
+
React から利用する場合は `@gasboost/react` の `useAppsScriptJob` を利用できます。
|
|
313
|
+
|
|
314
|
+
## History
|
|
315
|
+
|
|
316
|
+
`AppsScriptHistoryPipeline` は Google Apps Script Web アプリケーションの navigation state を同期するための仕組みです。
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
import { AppsScriptHistoryPipeline } from "@gasboost/client";
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Google Apps Script が提供する、
|
|
323
|
+
|
|
324
|
+
- `google.script.history`
|
|
325
|
+
- `google.script.url`
|
|
326
|
+
|
|
327
|
+
と iframe 側の History を同期します。
|
|
328
|
+
|
|
329
|
+
```text
|
|
330
|
+
GAS Container History
|
|
331
|
+
↕
|
|
332
|
+
AppsScriptHistoryPipeline
|
|
333
|
+
↕
|
|
334
|
+
iframe History
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
通常 React アプリケーションでは、直接利用する代わりに `@gasboost/react` の `AppsScriptRouter` を利用します。
|
|
338
|
+
|
|
339
|
+
## Export
|
|
340
|
+
|
|
341
|
+
現在 `@gasboost/client` から公開されている API:
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
appsScriptClient;
|
|
345
|
+
AppsScriptJob;
|
|
346
|
+
AppsScriptJobStore;
|
|
347
|
+
AppsScriptHistoryPipeline;
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## ローカル RPC について
|
|
351
|
+
|
|
352
|
+
`@gasboost/vite` の `dev` plugin は、Vite Dev Server 上に Local RPC endpoint を提供します。
|
|
353
|
+
|
|
354
|
+
```text
|
|
355
|
+
POST /__gasboost/{rpcName}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
ただし現在の `@gasboost/client` の RPC transport は `google.script.run` を利用します。
|
|
359
|
+
|
|
360
|
+
そのため、`@gasboost/vite` の Local RPC endpoint へ自動的に transport を切り替える機能は、現在の `@gasboost/client` には含まれていません。
|
|
361
|
+
|
|
362
|
+
## 責務
|
|
363
|
+
|
|
364
|
+
`@gasboost/client` が担当するもの:
|
|
365
|
+
|
|
366
|
+
- `AppType` に基づく型安全 RPC client
|
|
367
|
+
- `google.script.run` を利用した RPC transport
|
|
368
|
+
- JSON response の parse
|
|
369
|
+
- RPC / 非同期処理の Job Queue
|
|
370
|
+
- Job の状態管理
|
|
371
|
+
- pending Job の cancel
|
|
372
|
+
- Job の retry
|
|
373
|
+
- Job Store の購読
|
|
374
|
+
- GAS Container と iframe の History 同期
|
|
375
|
+
|
|
376
|
+
React 固有の処理は `@gasboost/react` が担当します。
|
|
377
|
+
|
|
378
|
+
## 関連パッケージ
|
|
379
|
+
|
|
380
|
+
- `@gasboost/app` — バックエンドと RPC 契約の定義
|
|
381
|
+
- `@gasboost/vite` — GAS build と Local RPC
|
|
382
|
+
- `@gasboost/react` — React integration
|
|
383
|
+
|
|
384
|
+
## License
|
|
385
|
+
|
|
386
|
+
MIT
|
|
@@ -36,10 +36,11 @@ class AppsScriptIframe {
|
|
|
36
36
|
return this.entry;
|
|
37
37
|
}
|
|
38
38
|
read() {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const normalized = new HashProperty_1.HashProperty(window.location.hash)
|
|
40
|
+
.toString()
|
|
41
|
+
.replace(/^#/, "");
|
|
42
|
+
const [path = "/", query = ""] = normalized.split("?");
|
|
43
|
+
return new NavigationEntry_1.NavigationEntry(history.state ?? {}, new NavigationLocation_1.NavigationLocation(new HashProperty_1.HashProperty(path), new URLSearchParams(query)));
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
exports.AppsScriptIframe = AppsScriptIframe;
|
package/package.json
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gasboost/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Type-safe Google Apps Script RPC client with jobs and navigation.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/gasboost/app.git",
|
|
8
|
+
"directory": "packages/client"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "tiger-oshima",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"google-apps-script",
|
|
14
|
+
"gas",
|
|
15
|
+
"rpc",
|
|
16
|
+
"typescript",
|
|
17
|
+
"web-app",
|
|
18
|
+
"gasboost"
|
|
19
|
+
],
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
4
24
|
"main": "./dist/index.js",
|
|
5
25
|
"types": "./dist/index.d.ts",
|
|
6
26
|
"exports": {
|
package/dist/AppsScriptJob.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export declare class AppsScriptJob<T> {
|
|
2
|
-
readonly label: string;
|
|
3
|
-
readonly execute: () => Promise<T>;
|
|
4
|
-
private resolve;
|
|
5
|
-
private reject;
|
|
6
|
-
readonly id: string;
|
|
7
|
-
readonly createdAt: Date;
|
|
8
|
-
private _startedAt;
|
|
9
|
-
private _endedAt;
|
|
10
|
-
private _result;
|
|
11
|
-
private _error;
|
|
12
|
-
constructor(label: string, execute: () => Promise<T>, resolve: (value: T) => void, reject: (reason?: any) => void, id?: string, createdAt?: Date);
|
|
13
|
-
start(): void;
|
|
14
|
-
success(result: T): void;
|
|
15
|
-
fail(error: unknown): void;
|
|
16
|
-
get endedAt(): Date | null;
|
|
17
|
-
get result(): T | null;
|
|
18
|
-
get error(): unknown;
|
|
19
|
-
isPending(): boolean;
|
|
20
|
-
isRunning(): boolean;
|
|
21
|
-
isSuccess(): boolean;
|
|
22
|
-
isFailed(): boolean;
|
|
23
|
-
get status(): "failed" | "pending" | "running" | "success" | "unknown";
|
|
24
|
-
cancel(): boolean;
|
|
25
|
-
}
|
|
26
|
-
export declare class AppsScriptJobCancelledError extends Error {
|
|
27
|
-
constructor();
|
|
28
|
-
}
|
package/dist/AppsScriptJob.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AppsScriptJobCancelledError = exports.AppsScriptJob = void 0;
|
|
4
|
-
class AppsScriptJob {
|
|
5
|
-
label;
|
|
6
|
-
execute;
|
|
7
|
-
resolve;
|
|
8
|
-
reject;
|
|
9
|
-
id;
|
|
10
|
-
createdAt;
|
|
11
|
-
_startedAt = null;
|
|
12
|
-
_endedAt = null;
|
|
13
|
-
_result = null;
|
|
14
|
-
_error = null;
|
|
15
|
-
constructor(label, execute, resolve, reject, id = crypto.randomUUID(), createdAt = new Date()) {
|
|
16
|
-
this.label = label;
|
|
17
|
-
this.execute = execute;
|
|
18
|
-
this.resolve = resolve;
|
|
19
|
-
this.reject = reject;
|
|
20
|
-
this.id = id;
|
|
21
|
-
this.createdAt = createdAt;
|
|
22
|
-
}
|
|
23
|
-
start() {
|
|
24
|
-
this._startedAt = new Date();
|
|
25
|
-
}
|
|
26
|
-
success(result) {
|
|
27
|
-
this._endedAt = new Date();
|
|
28
|
-
this._result = result;
|
|
29
|
-
this.resolve(result);
|
|
30
|
-
}
|
|
31
|
-
fail(error) {
|
|
32
|
-
this._endedAt = new Date();
|
|
33
|
-
this._error = error;
|
|
34
|
-
this.reject(error);
|
|
35
|
-
}
|
|
36
|
-
get endedAt() {
|
|
37
|
-
return this._endedAt;
|
|
38
|
-
}
|
|
39
|
-
get result() {
|
|
40
|
-
return this._result;
|
|
41
|
-
}
|
|
42
|
-
get error() {
|
|
43
|
-
return this._error;
|
|
44
|
-
}
|
|
45
|
-
isPending() {
|
|
46
|
-
return this._startedAt === null;
|
|
47
|
-
}
|
|
48
|
-
isRunning() {
|
|
49
|
-
return this._startedAt !== null && this._endedAt === null;
|
|
50
|
-
}
|
|
51
|
-
isSuccess() {
|
|
52
|
-
return this._endedAt !== null && this._error === null;
|
|
53
|
-
}
|
|
54
|
-
isFailed() {
|
|
55
|
-
return this._endedAt !== null && this._error !== null;
|
|
56
|
-
}
|
|
57
|
-
get status() {
|
|
58
|
-
if (this.isPending())
|
|
59
|
-
return "pending";
|
|
60
|
-
if (this.isRunning())
|
|
61
|
-
return "running";
|
|
62
|
-
if (this.isSuccess())
|
|
63
|
-
return "success";
|
|
64
|
-
if (this.isFailed())
|
|
65
|
-
return "failed";
|
|
66
|
-
return "unknown";
|
|
67
|
-
}
|
|
68
|
-
cancel() {
|
|
69
|
-
if (!this.isPending()) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
const error = new AppsScriptJobCancelledError();
|
|
73
|
-
this.fail(error);
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
exports.AppsScriptJob = AppsScriptJob;
|
|
78
|
-
class AppsScriptJobCancelledError extends Error {
|
|
79
|
-
constructor() {
|
|
80
|
-
super("Job cancelled");
|
|
81
|
-
this.name = "AppsScriptJobCancelledError";
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
exports.AppsScriptJobCancelledError = AppsScriptJobCancelledError;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { AppsScriptJob } from "./AppsScriptJob";
|
|
2
|
-
export interface RunnableJob {
|
|
3
|
-
run(): Promise<void>;
|
|
4
|
-
addJob<T>(job: AppsScriptJob<T>): void;
|
|
5
|
-
}
|
|
6
|
-
export declare class AppsScriptJobQueue {
|
|
7
|
-
private jobs;
|
|
8
|
-
private listeners;
|
|
9
|
-
enqueue<T>(label: string, execute: () => Promise<T>): Promise<T>;
|
|
10
|
-
dequeue(): AppsScriptJob<any> | undefined;
|
|
11
|
-
private notify;
|
|
12
|
-
subscribe(listener: RunnableJob): () => boolean;
|
|
13
|
-
remove(jobId: string): void;
|
|
14
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AppsScriptJobQueue = void 0;
|
|
4
|
-
const AppsScriptJob_1 = require("./AppsScriptJob");
|
|
5
|
-
class AppsScriptJobQueue {
|
|
6
|
-
jobs = [];
|
|
7
|
-
listeners = new Set();
|
|
8
|
-
enqueue(label, execute) {
|
|
9
|
-
const promise = new Promise((resolve, reject) => {
|
|
10
|
-
// キューにジョブを追加
|
|
11
|
-
const job = new AppsScriptJob_1.AppsScriptJob(label, execute, resolve, reject);
|
|
12
|
-
this.jobs.push(job);
|
|
13
|
-
this.notify(job);
|
|
14
|
-
});
|
|
15
|
-
return promise;
|
|
16
|
-
}
|
|
17
|
-
dequeue() {
|
|
18
|
-
const job = this.jobs.shift();
|
|
19
|
-
if (!job)
|
|
20
|
-
return undefined;
|
|
21
|
-
return job;
|
|
22
|
-
}
|
|
23
|
-
notify(job) {
|
|
24
|
-
this.listeners.forEach((listener) => {
|
|
25
|
-
listener.addJob(job);
|
|
26
|
-
listener.run();
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
subscribe(listener) {
|
|
30
|
-
this.listeners.add(listener);
|
|
31
|
-
return () => this.listeners.delete(listener);
|
|
32
|
-
}
|
|
33
|
-
remove(jobId) {
|
|
34
|
-
const index = this.jobs.findIndex((job) => job.id === jobId);
|
|
35
|
-
if (index !== -1) {
|
|
36
|
-
this.jobs.splice(index, 1);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
exports.AppsScriptJobQueue = AppsScriptJobQueue;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { AppsScriptJob } from "./AppsScriptJob";
|
|
2
|
-
import { AppsScriptJobQueue, RunnableJob } from "./AppsScriptJobQueue";
|
|
3
|
-
export declare class AppsScriptJobRunner implements RunnableJob {
|
|
4
|
-
readonly queue: AppsScriptJobQueue;
|
|
5
|
-
private jobs;
|
|
6
|
-
private listeners;
|
|
7
|
-
private MAX_CONCURRENT;
|
|
8
|
-
private running;
|
|
9
|
-
private snapshot;
|
|
10
|
-
private dirty;
|
|
11
|
-
constructor(queue: AppsScriptJobQueue);
|
|
12
|
-
addJob<T>(job: AppsScriptJob<T>): void;
|
|
13
|
-
getJobs(): AppsScriptJob<any>[];
|
|
14
|
-
run(): Promise<void>;
|
|
15
|
-
remove(jobId: string): void;
|
|
16
|
-
cancel(jobId: string): void;
|
|
17
|
-
retry(jobId: AppsScriptJob<any>["id"]): void;
|
|
18
|
-
subscribe(listener: () => void): () => boolean;
|
|
19
|
-
private notify;
|
|
20
|
-
}
|