@fairfox/polly 0.12.3 → 0.13.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/src/background/index.js +118 -1
- package/dist/src/background/index.js.map +5 -4
- package/dist/src/background/message-router.js +118 -1
- package/dist/src/background/message-router.js.map +5 -4
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +203 -3
- package/dist/src/index.js.map +9 -6
- package/dist/src/shared/lib/constraints.d.ts +61 -0
- package/dist/src/shared/lib/context-helpers.js +118 -1
- package/dist/src/shared/lib/context-helpers.js.map +5 -4
- package/dist/src/shared/lib/message-bus.d.ts +22 -0
- package/dist/src/shared/lib/message-bus.js +118 -1
- package/dist/src/shared/lib/message-bus.js.map +5 -4
- package/dist/src/shared/lib/state.d.ts +8 -2
- package/dist/src/shared/lib/state.js +140 -3
- package/dist/src/shared/lib/state.js.map +6 -5
- package/dist/src/shared/lib/validation.d.ts +94 -0
- package/dist/src/shared/state/app-state.d.ts +4 -1
- package/dist/src/shared/state/app-state.js +140 -3
- package/dist/src/shared/state/app-state.js.map +6 -5
- package/dist/tools/analysis/src/extract/handlers.d.ts +24 -2
- package/dist/tools/teach/src/cli.js +102 -17
- package/dist/tools/teach/src/cli.js.map +3 -3
- package/dist/tools/teach/src/index.js +102 -17
- package/dist/tools/teach/src/index.js.map +3 -3
- package/dist/tools/verify/Dockerfile +11 -7
- package/dist/tools/verify/specs/Dockerfile +21 -5
- package/dist/tools/verify/specs/README.md +13 -6
- package/dist/tools/verify/src/cli.js +102 -17
- package/dist/tools/verify/src/cli.js.map +3 -3
- package/dist/tools/verify/src/config.js +8 -2
- package/dist/tools/verify/src/config.js.map +3 -3
- package/dist/tools/verify/src/primitives/index.d.ts +21 -8
- package/dist/tools/visualize/src/cli.js +102 -17
- package/dist/tools/visualize/src/cli.js.map +3 -3
- package/package.json +1 -1
|
@@ -48,6 +48,90 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
48
48
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
// src/shared/lib/constraints.ts
|
|
52
|
+
var exports_constraints = {};
|
|
53
|
+
__export(exports_constraints, {
|
|
54
|
+
registerConstraints: () => registerConstraints,
|
|
55
|
+
registerConstraint: () => registerConstraint,
|
|
56
|
+
isRuntimeConstraintsEnabled: () => isRuntimeConstraintsEnabled,
|
|
57
|
+
getRegisteredConstraints: () => getRegisteredConstraints,
|
|
58
|
+
clearConstraints: () => clearConstraints,
|
|
59
|
+
checkPreconditions: () => checkPreconditions,
|
|
60
|
+
checkPostconditions: () => checkPostconditions
|
|
61
|
+
});
|
|
62
|
+
function registerConstraint(field, messageType, constraint) {
|
|
63
|
+
if (!registry.has(field)) {
|
|
64
|
+
registry.set(field, new Map);
|
|
65
|
+
}
|
|
66
|
+
registry.get(field)?.set(messageType, constraint);
|
|
67
|
+
}
|
|
68
|
+
function registerConstraints(field, constraints) {
|
|
69
|
+
for (const [messageType, constraint] of Object.entries(constraints)) {
|
|
70
|
+
const runtimeConstraint = {
|
|
71
|
+
message: constraint.message
|
|
72
|
+
};
|
|
73
|
+
if (typeof constraint.requires === "function") {
|
|
74
|
+
runtimeConstraint.requires = constraint.requires;
|
|
75
|
+
}
|
|
76
|
+
if (typeof constraint.ensures === "function") {
|
|
77
|
+
runtimeConstraint.ensures = constraint.ensures;
|
|
78
|
+
}
|
|
79
|
+
if (runtimeConstraint.requires || runtimeConstraint.ensures) {
|
|
80
|
+
registerConstraint(field, messageType, runtimeConstraint);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function executeConstraint(predicate, state, messageType, field, customMessage, constraintType = "Precondition") {
|
|
85
|
+
try {
|
|
86
|
+
const result = predicate(state);
|
|
87
|
+
if (!result) {
|
|
88
|
+
const message = customMessage || `${constraintType} failed for ${messageType} on field ${field}`;
|
|
89
|
+
throw new Error(message);
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error instanceof Error && error.message.includes(`${constraintType} failed`)) {
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
const message = customMessage || `${constraintType} check error for ${messageType} on field ${field}`;
|
|
96
|
+
throw new Error(`${message}: ${error}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function checkPreconditions(messageType, state) {
|
|
100
|
+
for (const [field, constraints] of registry) {
|
|
101
|
+
const constraint = constraints.get(messageType);
|
|
102
|
+
if (constraint?.requires) {
|
|
103
|
+
executeConstraint(constraint.requires, state, messageType, field, constraint.message, "Precondition");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function checkPostconditions(messageType, state) {
|
|
108
|
+
for (const [field, constraints] of registry) {
|
|
109
|
+
const constraint = constraints.get(messageType);
|
|
110
|
+
if (constraint?.ensures) {
|
|
111
|
+
executeConstraint(constraint.ensures, state, messageType, field, constraint.message, "Postcondition");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function clearConstraints() {
|
|
116
|
+
registry.clear();
|
|
117
|
+
}
|
|
118
|
+
function getRegisteredConstraints() {
|
|
119
|
+
return new Map(registry);
|
|
120
|
+
}
|
|
121
|
+
function isRuntimeConstraintsEnabled() {
|
|
122
|
+
if (typeof process !== "undefined" && process.env) {
|
|
123
|
+
return process.env["POLLY_RUNTIME_CONSTRAINTS"] === "true";
|
|
124
|
+
}
|
|
125
|
+
if (typeof Bun !== "undefined" && Bun.env) {
|
|
126
|
+
return Bun.env["POLLY_RUNTIME_CONSTRAINTS"] === "true";
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
var registry;
|
|
131
|
+
var init_constraints = __esm(() => {
|
|
132
|
+
registry = new Map;
|
|
133
|
+
});
|
|
134
|
+
|
|
51
135
|
// src/shared/adapters/chrome/context-menus.chrome.ts
|
|
52
136
|
class ChromeContextMenusAdapter {
|
|
53
137
|
async create(createProperties) {
|
|
@@ -724,6 +808,7 @@ class MessageBus {
|
|
|
724
808
|
port = null;
|
|
725
809
|
errorHandler;
|
|
726
810
|
userErrorHandlers = [];
|
|
811
|
+
stateAccessor = null;
|
|
727
812
|
messageListener = null;
|
|
728
813
|
constructor(context, adapters, options) {
|
|
729
814
|
this.context = context;
|
|
@@ -811,6 +896,9 @@ class MessageBus {
|
|
|
811
896
|
onError(handler) {
|
|
812
897
|
this.userErrorHandlers.push(handler);
|
|
813
898
|
}
|
|
899
|
+
setStateAccessor(accessor) {
|
|
900
|
+
this.stateAccessor = accessor;
|
|
901
|
+
}
|
|
814
902
|
async sendToBackground(payload, options) {
|
|
815
903
|
return this.send(payload, { ...options, target: "background" });
|
|
816
904
|
}
|
|
@@ -968,11 +1056,40 @@ class MessageBus {
|
|
|
968
1056
|
}
|
|
969
1057
|
try {
|
|
970
1058
|
globalExecutionTracker.track(message.id, message.payload.type);
|
|
1059
|
+
if (this.stateAccessor) {
|
|
1060
|
+
try {
|
|
1061
|
+
const { checkPreconditions: checkPreconditions2, isRuntimeConstraintsEnabled: isRuntimeConstraintsEnabled2 } = await Promise.resolve().then(() => (init_constraints(), exports_constraints));
|
|
1062
|
+
if (isRuntimeConstraintsEnabled2()) {
|
|
1063
|
+
const currentState = this.stateAccessor();
|
|
1064
|
+
checkPreconditions2(message.payload.type, currentState);
|
|
1065
|
+
}
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
if (error instanceof Error) {
|
|
1068
|
+
throw error;
|
|
1069
|
+
}
|
|
1070
|
+
if (error && typeof error === "object" && "code" in error && error.code === "MODULE_NOT_FOUND") {} else {
|
|
1071
|
+
throw error;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
971
1075
|
const handler = handlers[0];
|
|
972
1076
|
if (!handler) {
|
|
973
1077
|
throw new Error(`Handler not found for ${message.payload.type}`);
|
|
974
1078
|
}
|
|
975
1079
|
const data = await handler(message.payload, message);
|
|
1080
|
+
if (this.stateAccessor) {
|
|
1081
|
+
try {
|
|
1082
|
+
const { checkPostconditions: checkPostconditions2, isRuntimeConstraintsEnabled: isRuntimeConstraintsEnabled2 } = await Promise.resolve().then(() => (init_constraints(), exports_constraints));
|
|
1083
|
+
if (isRuntimeConstraintsEnabled2()) {
|
|
1084
|
+
const currentState = this.stateAccessor();
|
|
1085
|
+
checkPostconditions2(message.payload.type, currentState);
|
|
1086
|
+
}
|
|
1087
|
+
} catch (error) {
|
|
1088
|
+
if (error instanceof Error && error.message.includes("Postcondition")) {
|
|
1089
|
+
console.error(`[${this.context}] Postcondition failed:`, error.message);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
976
1093
|
const response = {
|
|
977
1094
|
id: message.id,
|
|
978
1095
|
success: true,
|
|
@@ -1115,11 +1232,16 @@ function getCurrentContext() {
|
|
|
1115
1232
|
return "background";
|
|
1116
1233
|
}
|
|
1117
1234
|
function $sharedState(key, initialValue, options = {}) {
|
|
1118
|
-
|
|
1235
|
+
const sig = createState(key, initialValue, {
|
|
1119
1236
|
...options,
|
|
1120
1237
|
sync: true,
|
|
1121
1238
|
persist: true
|
|
1122
1239
|
});
|
|
1240
|
+
const entry = stateRegistry.get(key);
|
|
1241
|
+
if (entry) {
|
|
1242
|
+
sig.loaded = entry.loaded;
|
|
1243
|
+
}
|
|
1244
|
+
return sig;
|
|
1123
1245
|
}
|
|
1124
1246
|
function $syncedState(key, initialValue, options = {}) {
|
|
1125
1247
|
return createState(key, initialValue, {
|
|
@@ -1129,11 +1251,16 @@ function $syncedState(key, initialValue, options = {}) {
|
|
|
1129
1251
|
});
|
|
1130
1252
|
}
|
|
1131
1253
|
function $persistedState(key, initialValue, options = {}) {
|
|
1132
|
-
|
|
1254
|
+
const sig = createState(key, initialValue, {
|
|
1133
1255
|
...options,
|
|
1134
1256
|
sync: false,
|
|
1135
1257
|
persist: true
|
|
1136
1258
|
});
|
|
1259
|
+
const entry = stateRegistry.get(key);
|
|
1260
|
+
if (entry) {
|
|
1261
|
+
sig.loaded = entry.loaded;
|
|
1262
|
+
}
|
|
1263
|
+
return sig;
|
|
1137
1264
|
}
|
|
1138
1265
|
function $state(initialValue) {
|
|
1139
1266
|
return signal(initialValue);
|
|
@@ -1169,6 +1296,10 @@ Page scripts are execution contexts for content scripts and should not maintain
|
|
|
1169
1296
|
Use state in the content script instead, or use $state() for local-only state.`);
|
|
1170
1297
|
}
|
|
1171
1298
|
const sig = signal(initialValue);
|
|
1299
|
+
if (options.verify) {
|
|
1300
|
+
const mirror = JSON.parse(JSON.stringify(initialValue));
|
|
1301
|
+
sig.verify = mirror;
|
|
1302
|
+
}
|
|
1172
1303
|
const entry = {
|
|
1173
1304
|
signal: sig,
|
|
1174
1305
|
clock: 0,
|
|
@@ -1201,6 +1332,12 @@ Use state in the content script instead, or use $state() for local-only state.`)
|
|
|
1201
1332
|
return;
|
|
1202
1333
|
}
|
|
1203
1334
|
previousValue = value;
|
|
1335
|
+
if (options.verify) {
|
|
1336
|
+
const verifySignal = sig;
|
|
1337
|
+
if (verifySignal.verify) {
|
|
1338
|
+
Object.assign(verifySignal.verify, JSON.parse(JSON.stringify(value)));
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1204
1341
|
entry.clock++;
|
|
1205
1342
|
const doUpdate = () => {
|
|
1206
1343
|
if (options.persist) {
|
|
@@ -1319,4 +1456,4 @@ export {
|
|
|
1319
1456
|
$persistedState
|
|
1320
1457
|
};
|
|
1321
1458
|
|
|
1322
|
-
//# debugId=
|
|
1459
|
+
//# debugId=30E85DBFA071F76364756E2164756E21
|