@gasboost/client 0.1.0
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/dist/AppsScriptClient.d.ts +30 -0
- package/dist/AppsScriptClient.js +43 -0
- package/dist/AppsScriptJob.d.ts +28 -0
- package/dist/AppsScriptJob.js +84 -0
- package/dist/AppsScriptJobQueue.d.ts +14 -0
- package/dist/AppsScriptJobQueue.js +40 -0
- package/dist/AppsScriptJobRunner.d.ts +20 -0
- package/dist/AppsScriptJobRunner.js +93 -0
- package/dist/AppsScriptJobStore.d.ts +7 -0
- package/dist/AppsScriptJobStore.js +9 -0
- package/dist/google.d.ts +36 -0
- package/dist/google.js +8 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/job/AppsScriptJob.d.ts +28 -0
- package/dist/job/AppsScriptJob.js +84 -0
- package/dist/job/AppsScriptJobQueue.d.ts +14 -0
- package/dist/job/AppsScriptJobQueue.js +40 -0
- package/dist/job/AppsScriptJobRunner.d.ts +20 -0
- package/dist/job/AppsScriptJobRunner.js +93 -0
- package/dist/job/AppsScriptJobStore.d.ts +7 -0
- package/dist/job/AppsScriptJobStore.js +9 -0
- package/dist/navigation/AppsScriptContainer.d.ts +9 -0
- package/dist/navigation/AppsScriptContainer.js +38 -0
- package/dist/navigation/AppsScriptHistoryPipeline.d.ts +9 -0
- package/dist/navigation/AppsScriptHistoryPipeline.js +28 -0
- package/dist/navigation/AppsScriptIframe.d.ts +9 -0
- package/dist/navigation/AppsScriptIframe.js +45 -0
- package/dist/navigation/HashProperty.d.ts +7 -0
- package/dist/navigation/HashProperty.js +27 -0
- package/dist/navigation/NavigationEntry.d.ts +9 -0
- package/dist/navigation/NavigationEntry.js +54 -0
- package/dist/navigation/NavigationLocation.d.ts +8 -0
- package/dist/navigation/NavigationLocation.js +43 -0
- package/package.json +20 -0
- package/src/AppsScriptClient.ts +81 -0
- package/src/google.ts +55 -0
- package/src/index.ts +4 -0
- package/src/job/AppsScriptJob.ts +85 -0
- package/src/job/AppsScriptJobQueue.ts +48 -0
- package/src/job/AppsScriptJobRunner.ts +107 -0
- package/src/job/AppsScriptJobStore.ts +16 -0
- package/src/navigation/AppsScriptContainer.ts +47 -0
- package/src/navigation/AppsScriptHistoryPipeline.ts +29 -0
- package/src/navigation/AppsScriptIframe.ts +63 -0
- package/src/navigation/HashProperty.ts +20 -0
- package/src/navigation/NavigationEntry.ts +82 -0
- package/src/navigation/NavigationLocation.ts +54 -0
- package/tests/AppsScriptClient.spec.ts +322 -0
- package/tests/AppsScriptClient.type.spec.ts +52 -0
- package/tests/AppsScriptContainer.spec.ts +502 -0
- package/tests/AppsScriptHistoryPipeline.spec.ts +303 -0
- package/tests/AppsScriptIframe.spec.ts +452 -0
- package/tests/AppsScriptJob.spec.ts +83 -0
- package/tests/AppsScriptJobQueue.spec.ts +125 -0
- package/tests/AppsScriptJobRunner.spec.ts +361 -0
- package/tests/HashProperty.spec.ts +29 -0
- package/tests/NavigationEntry.spec.ts +507 -0
- package/tests/NavigationLocation.spec.ts +189 -0
- package/tests/setup.ts +15 -0
- package/tsconfig.build.json +14 -0
- package/tsconfig.json +6 -0
- package/vitest.config.mts +8 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AppsScriptJob } from "./job/AppsScriptJob";
|
|
2
|
+
type RpcResponse = {
|
|
3
|
+
contents: string;
|
|
4
|
+
};
|
|
5
|
+
type RpcDefinition = {
|
|
6
|
+
args: unknown[];
|
|
7
|
+
result: unknown;
|
|
8
|
+
};
|
|
9
|
+
type RpcApp = Record<string, RpcDefinition>;
|
|
10
|
+
type AppsScriptClient<TApp extends RpcApp> = {
|
|
11
|
+
[K in keyof TApp]: TApp[K] extends {
|
|
12
|
+
args: infer TArgs extends unknown[];
|
|
13
|
+
result: infer TResult;
|
|
14
|
+
} ? (...args: TArgs) => Promise<TResult> : never;
|
|
15
|
+
};
|
|
16
|
+
export declare const appsScriptTransport: {
|
|
17
|
+
call(name: string, args: unknown[]): Promise<RpcResponse>;
|
|
18
|
+
};
|
|
19
|
+
interface AppsScriptJobs {
|
|
20
|
+
start: <T>(label: string, execute: () => Promise<T>) => Promise<T>;
|
|
21
|
+
cancel: (jobId: string) => void;
|
|
22
|
+
retry: (jobId: string) => void;
|
|
23
|
+
subscribe: (listener: () => void) => () => void;
|
|
24
|
+
getSnapshot: () => AppsScriptJob<any>[];
|
|
25
|
+
}
|
|
26
|
+
export declare function appsScriptClient<TApp extends RpcApp>(): {
|
|
27
|
+
client: AppsScriptClient<TApp>;
|
|
28
|
+
jobs: AppsScriptJobs;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.appsScriptTransport = void 0;
|
|
4
|
+
exports.appsScriptClient = appsScriptClient;
|
|
5
|
+
const google_1 = require("./google");
|
|
6
|
+
const AppsScriptJobQueue_1 = require("./job/AppsScriptJobQueue");
|
|
7
|
+
const AppsScriptJobRunner_1 = require("./job/AppsScriptJobRunner");
|
|
8
|
+
const AppsScriptJobStore_1 = require("./job/AppsScriptJobStore");
|
|
9
|
+
exports.appsScriptTransport = {
|
|
10
|
+
call(name, args) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
google_1.google.script.run
|
|
13
|
+
.withSuccessHandler(resolve)
|
|
14
|
+
.withFailureHandler(reject)[name](...args);
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
function appsScriptClient() {
|
|
19
|
+
const jobQueue = new AppsScriptJobQueue_1.AppsScriptJobQueue();
|
|
20
|
+
const jobRunner = new AppsScriptJobRunner_1.AppsScriptJobRunner(jobQueue);
|
|
21
|
+
const jobStore = (0, AppsScriptJobStore_1.appsScriptJobStore)(jobRunner);
|
|
22
|
+
const client = new Proxy({}, {
|
|
23
|
+
get(_target, property) {
|
|
24
|
+
if (typeof property !== "string") {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return (...args) => {
|
|
28
|
+
return jobQueue.enqueue(property, async () => {
|
|
29
|
+
const res = await exports.appsScriptTransport.call(property, args);
|
|
30
|
+
return JSON.parse(res.contents);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
const jobs = {
|
|
36
|
+
start: jobQueue.enqueue.bind(jobQueue),
|
|
37
|
+
cancel: jobRunner.cancel.bind(jobRunner),
|
|
38
|
+
retry: jobRunner.retry.bind(jobRunner),
|
|
39
|
+
subscribe: jobStore.subscribe.bind(jobStore),
|
|
40
|
+
getSnapshot: jobStore.getSnapshot.bind(jobStore),
|
|
41
|
+
};
|
|
42
|
+
return { client, jobs };
|
|
43
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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;
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
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;
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppsScriptJobRunner = void 0;
|
|
4
|
+
class AppsScriptJobRunner {
|
|
5
|
+
queue;
|
|
6
|
+
jobs = [];
|
|
7
|
+
listeners = new Set();
|
|
8
|
+
MAX_CONCURRENT = 30;
|
|
9
|
+
running = false;
|
|
10
|
+
snapshot = null;
|
|
11
|
+
dirty = true;
|
|
12
|
+
constructor(queue) {
|
|
13
|
+
this.queue = queue;
|
|
14
|
+
this.queue.subscribe(this);
|
|
15
|
+
}
|
|
16
|
+
addJob(job) {
|
|
17
|
+
this.jobs.push(job);
|
|
18
|
+
this.notify();
|
|
19
|
+
}
|
|
20
|
+
getJobs() {
|
|
21
|
+
if (this.dirty || !this.snapshot) {
|
|
22
|
+
this.snapshot = [...this.jobs];
|
|
23
|
+
this.dirty = false;
|
|
24
|
+
}
|
|
25
|
+
return this.snapshot;
|
|
26
|
+
}
|
|
27
|
+
async run() {
|
|
28
|
+
if (this.running)
|
|
29
|
+
return;
|
|
30
|
+
this.running = true;
|
|
31
|
+
while (true) {
|
|
32
|
+
const runningCount = this.jobs.filter((j) => j.isRunning()).length;
|
|
33
|
+
if (runningCount >= this.MAX_CONCURRENT)
|
|
34
|
+
break;
|
|
35
|
+
const job = this.queue.dequeue();
|
|
36
|
+
if (!job)
|
|
37
|
+
break;
|
|
38
|
+
job.start();
|
|
39
|
+
this.notify();
|
|
40
|
+
job
|
|
41
|
+
.execute()
|
|
42
|
+
.then((result) => {
|
|
43
|
+
job.success(result);
|
|
44
|
+
const index = this.jobs.indexOf(job);
|
|
45
|
+
if (index !== -1) {
|
|
46
|
+
this.jobs.splice(index, 1);
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
.catch((error) => {
|
|
50
|
+
job.fail(error);
|
|
51
|
+
})
|
|
52
|
+
.finally(() => {
|
|
53
|
+
this.notify();
|
|
54
|
+
this.running = false;
|
|
55
|
+
this.run();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
this.running = false;
|
|
59
|
+
}
|
|
60
|
+
remove(jobId) {
|
|
61
|
+
const index = this.jobs.findIndex((job) => job.id === jobId);
|
|
62
|
+
if (index === -1) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this.jobs.splice(index, 1);
|
|
66
|
+
this.notify();
|
|
67
|
+
}
|
|
68
|
+
cancel(jobId) {
|
|
69
|
+
const job = this.jobs.find((job) => job.id === jobId);
|
|
70
|
+
if (!job || !job.cancel()) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.queue.remove(jobId);
|
|
74
|
+
this.jobs.splice(this.jobs.indexOf(job), 1);
|
|
75
|
+
this.notify();
|
|
76
|
+
}
|
|
77
|
+
retry(jobId) {
|
|
78
|
+
const job = this.jobs.find((j) => j.id === jobId);
|
|
79
|
+
if (job) {
|
|
80
|
+
this.remove(job.id);
|
|
81
|
+
this.queue.enqueue(job.label, job.execute);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
subscribe(listener) {
|
|
85
|
+
this.listeners.add(listener);
|
|
86
|
+
return () => this.listeners.delete(listener);
|
|
87
|
+
}
|
|
88
|
+
notify() {
|
|
89
|
+
this.dirty = true;
|
|
90
|
+
this.listeners.forEach((listener) => listener());
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.AppsScriptJobRunner = AppsScriptJobRunner;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AppsScriptJob } from "./AppsScriptJob";
|
|
2
|
+
import { AppsScriptJobRunner } from "./AppsScriptJobRunner";
|
|
3
|
+
export interface AppsScriptJobStore {
|
|
4
|
+
subscribe: (listener: () => void) => () => void;
|
|
5
|
+
getSnapshot: () => AppsScriptJob<any>[];
|
|
6
|
+
}
|
|
7
|
+
export declare function appsScriptJobStore(runner: AppsScriptJobRunner): AppsScriptJobStore;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.appsScriptJobStore = appsScriptJobStore;
|
|
4
|
+
function appsScriptJobStore(runner) {
|
|
5
|
+
return {
|
|
6
|
+
subscribe: runner.subscribe.bind(runner),
|
|
7
|
+
getSnapshot: runner.getJobs.bind(runner),
|
|
8
|
+
};
|
|
9
|
+
}
|
package/dist/google.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type GoogleScriptRun = {
|
|
2
|
+
withSuccessHandler<T = unknown>(callback: (result: T) => void): GoogleScriptRun;
|
|
3
|
+
withFailureHandler(callback: (error: Error) => void): GoogleScriptRun;
|
|
4
|
+
[serverFunctionName: string]: any;
|
|
5
|
+
};
|
|
6
|
+
export type GoogleScriptHistoryEvent = {
|
|
7
|
+
state: Record<string, unknown>;
|
|
8
|
+
location: {
|
|
9
|
+
hash: string;
|
|
10
|
+
parameter: Record<string, string>;
|
|
11
|
+
parameters: Record<string, string[]>;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export type GoogleScriptUrlLocation = {
|
|
15
|
+
hash: string;
|
|
16
|
+
parameter: Record<string, string>;
|
|
17
|
+
parameters: Record<string, string[]>;
|
|
18
|
+
};
|
|
19
|
+
export type GoogleApi = {
|
|
20
|
+
script: {
|
|
21
|
+
run: GoogleScriptRun;
|
|
22
|
+
history: {
|
|
23
|
+
push: (stateObject: Record<string, unknown>, params: Record<string, unknown>, hash: string) => void;
|
|
24
|
+
replace: (stateObject: Record<string, unknown>, params: Record<string, unknown>, hash: string) => void;
|
|
25
|
+
setChangeHandler: (callback: (event: GoogleScriptHistoryEvent) => void) => void;
|
|
26
|
+
};
|
|
27
|
+
url: {
|
|
28
|
+
getLocation: (callback: (location: GoogleScriptUrlLocation) => void) => void;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* google.script.* は Apps Script のランタイムが注入するグローバル。
|
|
34
|
+
* ここでは「型付きで参照」だけ提供する。
|
|
35
|
+
*/
|
|
36
|
+
export declare const google: GoogleApi;
|
package/dist/google.js
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppsScriptHistoryPipeline = exports.appsScriptClient = void 0;
|
|
4
|
+
var AppsScriptClient_1 = require("./AppsScriptClient");
|
|
5
|
+
Object.defineProperty(exports, "appsScriptClient", { enumerable: true, get: function () { return AppsScriptClient_1.appsScriptClient; } });
|
|
6
|
+
var AppsScriptHistoryPipeline_1 = require("./navigation/AppsScriptHistoryPipeline");
|
|
7
|
+
Object.defineProperty(exports, "AppsScriptHistoryPipeline", { enumerable: true, get: function () { return AppsScriptHistoryPipeline_1.AppsScriptHistoryPipeline; } });
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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;
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
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;
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
}
|