@degenerate/events 0.2.5 → 0.3.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/bridge/index.d.ts +3 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +18 -0
- package/dist/bridge/scheduler-trigger.d.ts +34 -0
- package/dist/bridge/scheduler-trigger.d.ts.map +1 -0
- package/dist/bridge/scheduler-trigger.js +43 -0
- package/dist/bridge/transaction-proposer.d.ts +29 -0
- package/dist/bridge/transaction-proposer.d.ts.map +1 -0
- package/dist/bridge/transaction-proposer.js +11 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/scheduler/scheduler.js +9 -9
- package/package.json +23 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./transaction-proposer"), exports);
|
|
18
|
+
__exportStar(require("./scheduler-trigger"), exports);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SafeScheduler } from '../scheduler';
|
|
2
|
+
import { TransactionProposalOutcome, TransactionProposalRequest, TransactionProposer } from './transaction-proposer';
|
|
3
|
+
/**
|
|
4
|
+
* Optional observer of a scheduled proposal's outcome. A fired scheduler task
|
|
5
|
+
* is synchronous but `propose` is async, so the trigger cannot hand the result
|
|
6
|
+
* back to whoever scheduled it — these hooks are how a settled or failed
|
|
7
|
+
* automated proposal becomes visible (logging, metrics, retry policy).
|
|
8
|
+
*/
|
|
9
|
+
export interface SchedulerTriggerObserver {
|
|
10
|
+
onProposalSettled?(request: TransactionProposalRequest, outcome: TransactionProposalOutcome): void;
|
|
11
|
+
onProposalFailed?(request: TransactionProposalRequest, error: unknown): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Drives the signed mutation path from the clock. Wraps a {@link SafeScheduler}:
|
|
15
|
+
* when a scheduled time comes due it asks the injected {@link TransactionProposer}
|
|
16
|
+
* to submit the proposal — the same gate a human propose hits. The trigger
|
|
17
|
+
* itself holds no keys and never touches block state; that all lives behind the
|
|
18
|
+
* port, keeping `events` free of any `sharedata` dependency.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SchedulerTrigger {
|
|
21
|
+
private readonly scheduler;
|
|
22
|
+
private readonly proposer;
|
|
23
|
+
private readonly observer;
|
|
24
|
+
constructor(scheduler: SafeScheduler, proposer: TransactionProposer, observer?: SchedulerTriggerObserver);
|
|
25
|
+
/**
|
|
26
|
+
* Schedule `request` to be proposed at `time`. Returns the scheduler task
|
|
27
|
+
* id so the caller can {@link cancel} it (e.g. the block closed early).
|
|
28
|
+
*/
|
|
29
|
+
scheduleProposal(time: Date, request: TransactionProposalRequest): string;
|
|
30
|
+
/** Cancel a previously scheduled proposal that has not yet fired. */
|
|
31
|
+
cancel(taskId: string): void;
|
|
32
|
+
private fire;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=scheduler-trigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler-trigger.d.ts","sourceRoot":"","sources":["../../src/bridge/scheduler-trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACH,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACtB,MAAM,wBAAwB,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACrC,iBAAiB,CAAC,CACd,OAAO,EAAE,0BAA0B,EACnC,OAAO,EAAE,0BAA0B,GACpC,IAAI,CAAC;IACR,gBAAgB,CAAC,CAAC,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAChF;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAErB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAFR,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,GAAE,wBAA6B;IAG5D;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,0BAA0B,GAAG,MAAM;IASzE,qEAAqE;IACrE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;YAId,IAAI;CAQrB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SchedulerTrigger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Drives the signed mutation path from the clock. Wraps a {@link SafeScheduler}:
|
|
6
|
+
* when a scheduled time comes due it asks the injected {@link TransactionProposer}
|
|
7
|
+
* to submit the proposal — the same gate a human propose hits. The trigger
|
|
8
|
+
* itself holds no keys and never touches block state; that all lives behind the
|
|
9
|
+
* port, keeping `events` free of any `sharedata` dependency.
|
|
10
|
+
*/
|
|
11
|
+
class SchedulerTrigger {
|
|
12
|
+
constructor(scheduler, proposer, observer = {}) {
|
|
13
|
+
this.scheduler = scheduler;
|
|
14
|
+
this.proposer = proposer;
|
|
15
|
+
this.observer = observer;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Schedule `request` to be proposed at `time`. Returns the scheduler task
|
|
19
|
+
* id so the caller can {@link cancel} it (e.g. the block closed early).
|
|
20
|
+
*/
|
|
21
|
+
scheduleProposal(time, request) {
|
|
22
|
+
return this.scheduler.scheduleTask(time, () => {
|
|
23
|
+
// The scheduler callback is synchronous; the proposal is async, so
|
|
24
|
+
// fire-and-forget and route the eventual result/failure to the
|
|
25
|
+
// observer rather than letting a rejection go unhandled.
|
|
26
|
+
void this.fire(request);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Cancel a previously scheduled proposal that has not yet fired. */
|
|
30
|
+
cancel(taskId) {
|
|
31
|
+
this.scheduler.removeTask(taskId);
|
|
32
|
+
}
|
|
33
|
+
async fire(request) {
|
|
34
|
+
try {
|
|
35
|
+
const outcome = await this.proposer.propose(request);
|
|
36
|
+
this.observer.onProposalSettled?.(request, outcome);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
this.observer.onProposalFailed?.(request, error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.SchedulerTrigger = SchedulerTrigger;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** The intent a trigger hands to the proposer. */
|
|
2
|
+
export interface TransactionProposalRequest {
|
|
3
|
+
/** Id of the ShareData block to mutate. */
|
|
4
|
+
shareDataId: string;
|
|
5
|
+
/** Stable id of the registered function that produces the proposed state. */
|
|
6
|
+
functionId: string;
|
|
7
|
+
/** Input passed to that function (e.g. the close attribution). */
|
|
8
|
+
input?: unknown;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of attempting an automated proposal. `noOp` distinguishes "the
|
|
12
|
+
* function had nothing to propose" (e.g. closing an already-closed block) from
|
|
13
|
+
* a real rule rejection (`accepted: false, noOp: false`), mirroring
|
|
14
|
+
* `safeSubmitTransaction`'s three-way outcome.
|
|
15
|
+
*/
|
|
16
|
+
export interface TransactionProposalOutcome {
|
|
17
|
+
accepted: boolean;
|
|
18
|
+
transactionId: string;
|
|
19
|
+
noOp: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Realizes a {@link TransactionProposalRequest} against the signed mutation
|
|
23
|
+
* path. The concrete implementation lives in the composition root; everything
|
|
24
|
+
* in `events` programs against this interface.
|
|
25
|
+
*/
|
|
26
|
+
export interface TransactionProposer {
|
|
27
|
+
propose(request: TransactionProposalRequest): Promise<TransactionProposalOutcome>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=transaction-proposer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-proposer.d.ts","sourceRoot":"","sources":["../../src/bridge/transaction-proposer.ts"],"names":[],"mappings":"AAUA,kDAAkD;AAClD,MAAM,WAAW,0BAA0B;IACvC,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAChC,OAAO,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CACrF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Port between a fired event trigger and the signed ShareData mutation path.
|
|
3
|
+
//
|
|
4
|
+
// `events` deliberately knows nothing about `ShareDataManager`, proof minting,
|
|
5
|
+
// or how a function turns current state into proposed state. A trigger only
|
|
6
|
+
// expresses *intent* — "invoke this function on this block with this input" —
|
|
7
|
+
// and an injected `TransactionProposer` (implemented in the composition root,
|
|
8
|
+
// where `sharedata` is available) realizes it against the same gated path a
|
|
9
|
+
// human proposal uses (`ShareDataManager.applyTransaction`). Keeping this seam
|
|
10
|
+
// here is what lets `events` stay a light leaf with no `sharedata` dependency.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAC;AAM5B,cAAc,QAAQ,CAAC;AAMvB,cAAc,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
//#region Scheduler
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
__exportStar(require("./scheduler"), exports);
|
|
3
19
|
//#endregion Scheduler
|
|
4
20
|
//#region Task
|
|
21
|
+
__exportStar(require("./task"), exports);
|
|
5
22
|
//#endregion Task
|
|
23
|
+
//#region Bridge
|
|
24
|
+
__exportStar(require("./bridge"), exports);
|
|
25
|
+
//#endregion Bridge
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,KAAK,CAAkB;IAE/B;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM;IAQtF;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAehC;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,KAAK,CAAkB;IAE/B;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM;IAQtF;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAehC;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,IAAI;IAanD;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,OAAO;CAalB"}
|
|
@@ -52,15 +52,14 @@ class SafeScheduler {
|
|
|
52
52
|
*/
|
|
53
53
|
updateTaskTime(taskId, newTime) {
|
|
54
54
|
const task = this.tasks.find(task => task.id === taskId);
|
|
55
|
-
if (task) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
task.
|
|
60
|
-
this.scheduleNextTask(task); // Reschedule the task
|
|
61
|
-
console.log(`Task ${taskId} rescheduled for ${newTime.toUTCString()}.`);
|
|
55
|
+
if (!task) {
|
|
56
|
+
throw new generic_1.TaskNotFoundError(taskId);
|
|
57
|
+
}
|
|
58
|
+
if (task.timeoutId) {
|
|
59
|
+
clearTimeout(task.timeoutId); // Clear the existing timeout
|
|
62
60
|
}
|
|
63
|
-
|
|
61
|
+
task.time = newTime; // Update the time
|
|
62
|
+
this.scheduleNextTask(task); // Reschedule the task
|
|
64
63
|
}
|
|
65
64
|
// Helper to schedule the task based on date and time
|
|
66
65
|
/**
|
|
@@ -83,7 +82,8 @@ class SafeScheduler {
|
|
|
83
82
|
}
|
|
84
83
|
// Executes the task and reschedules it if it's a recurring task
|
|
85
84
|
runTask(task) {
|
|
86
|
-
|
|
85
|
+
// `callback()` returns the stored function; the trailing () invokes it.
|
|
86
|
+
task.callback()();
|
|
87
87
|
if (task.interval !== null) {
|
|
88
88
|
// If the task is recurring, reschedule it based on the interval
|
|
89
89
|
task.time = new Date(new Date().getTime() + task.interval);
|
package/package.json
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@degenerate/events",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "This contains the ShareData Adaptive Framework Ecosystem (SAFE) network event code",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
7
16
|
"scripts": {
|
|
8
17
|
"build": "rm -rf dist/* && tsc -p tsconfig.pkg.json",
|
|
9
18
|
"compile": "rm -rf dist/* && tsc -p tsconfig.pkg.json",
|
|
10
|
-
"test": "jest --forceExit --detectOpenHandles --verbose --silent=false --env node
|
|
11
|
-
"test:coverage": "jest --forceExit --coverage --detectOpenHandles --verbose --silent=false --env node
|
|
19
|
+
"test": "jest --forceExit --detectOpenHandles --verbose --silent=false --env node",
|
|
20
|
+
"test:coverage": "jest --forceExit --coverage --detectOpenHandles --verbose --silent=false --env node ",
|
|
12
21
|
"test:clearCache": "jest --clearCache"
|
|
13
22
|
},
|
|
14
23
|
"keywords": [
|
|
@@ -22,11 +31,11 @@
|
|
|
22
31
|
"author": "Degenerate Inc.",
|
|
23
32
|
"license": "ISC",
|
|
24
33
|
"devDependencies": {
|
|
25
|
-
"@types/jest": "^
|
|
26
|
-
"@types/node": "^22.
|
|
27
|
-
"jest": "^
|
|
28
|
-
"ts-jest": "^29.
|
|
29
|
-
"typescript": "^
|
|
34
|
+
"@types/jest": "^30.0.0",
|
|
35
|
+
"@types/node": "^22.19.18",
|
|
36
|
+
"jest": "^30.4.2",
|
|
37
|
+
"ts-jest": "^29.4.9",
|
|
38
|
+
"typescript": "^6.0.3"
|
|
30
39
|
},
|
|
31
40
|
"repository": {
|
|
32
41
|
"type": "git",
|
|
@@ -37,8 +46,11 @@
|
|
|
37
46
|
},
|
|
38
47
|
"homepage": "https://github.com/syncrude/safe#readme",
|
|
39
48
|
"dependencies": {
|
|
40
|
-
"@degenerate/generic": "^0.
|
|
41
|
-
"zod": "^
|
|
49
|
+
"@degenerate/generic": "^0.3.0",
|
|
50
|
+
"zod": "^4.4.3"
|
|
42
51
|
},
|
|
43
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "c33ed2f06679f5bd76c2eccf7054212c1820a014",
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=22"
|
|
55
|
+
}
|
|
44
56
|
}
|