Bhargava 6063bd1724 Help Project:
1. Initial Commit - a boiler plate code and POC to realize the concept of context
sensitive help
2. Frontend code written in ReactJS
3. Backend code written in Java, Spring Boot Framework
4. Frontend Start:
        pre-requisites : node, npm
	npm run dev  ==> to start the frontend vite server
5. Backend Start:
	pre-requisites : java, mvn
        mvn spring-boot:run  ==> to start the backend server
6. Visit http://localhost:5173/ for basic demo of help, press F1 in textboxes
7. Visit http://localhost:5173/editor and enter "admin123" to add/modify texts.

Happy Coding !!!

Thank you,
Bhargava.
2025-07-04 15:54:13 +05:30

374 lines
9.4 KiB
JavaScript

"use strict";
// These use the global symbol registry so that multiple copies of this
// library can work together in case they are not deduped.
const GENSYNC_START = Symbol.for("gensync:v1:start");
const GENSYNC_SUSPEND = Symbol.for("gensync:v1:suspend");
const GENSYNC_EXPECTED_START = "GENSYNC_EXPECTED_START";
const GENSYNC_EXPECTED_SUSPEND = "GENSYNC_EXPECTED_SUSPEND";
const GENSYNC_OPTIONS_ERROR = "GENSYNC_OPTIONS_ERROR";
const GENSYNC_RACE_NONEMPTY = "GENSYNC_RACE_NONEMPTY";
const GENSYNC_ERRBACK_NO_CALLBACK = "GENSYNC_ERRBACK_NO_CALLBACK";
module.exports = Object.assign(
function gensync(optsOrFn) {
let genFn = optsOrFn;
if (typeof optsOrFn !== "function") {
genFn = newGenerator(optsOrFn);
} else {
genFn = wrapGenerator(optsOrFn);
}
return Object.assign(genFn, makeFunctionAPI(genFn));
},
{
all: buildOperation({
name: "all",
arity: 1,
sync: function(args) {
const items = Array.from(args[0]);
return items.map(item => evaluateSync(item));
},
async: function(args, resolve, reject) {
const items = Array.from(args[0]);
if (items.length === 0) {
Promise.resolve().then(() => resolve([]));
return;
}
let count = 0;
const results = items.map(() => undefined);
items.forEach((item, i) => {
evaluateAsync(
item,
val => {
results[i] = val;
count += 1;
if (count === results.length) resolve(results);
},
reject
);
});
},
}),
race: buildOperation({
name: "race",
arity: 1,
sync: function(args) {
const items = Array.from(args[0]);
if (items.length === 0) {
throw makeError("Must race at least 1 item", GENSYNC_RACE_NONEMPTY);
}
return evaluateSync(items[0]);
},
async: function(args, resolve, reject) {
const items = Array.from(args[0]);
if (items.length === 0) {
throw makeError("Must race at least 1 item", GENSYNC_RACE_NONEMPTY);
}
for (const item of items) {
evaluateAsync(item, resolve, reject);
}
},
}),
}
);
/**
* Given a generator function, return the standard API object that executes
* the generator and calls the callbacks.
*/
function makeFunctionAPI(genFn) {
const fns = {
sync: function(...args) {
return evaluateSync(genFn.apply(this, args));
},
async: function(...args) {
return new Promise((resolve, reject) => {
evaluateAsync(genFn.apply(this, args), resolve, reject);
});
},
errback: function(...args) {
const cb = args.pop();
if (typeof cb !== "function") {
throw makeError(
"Asynchronous function called without callback",
GENSYNC_ERRBACK_NO_CALLBACK
);
}
let gen;
try {
gen = genFn.apply(this, args);
} catch (err) {
cb(err);
return;
}
evaluateAsync(gen, val => cb(undefined, val), err => cb(err));
},
};
return fns;
}
function assertTypeof(type, name, value, allowUndefined) {
if (
typeof value === type ||
(allowUndefined && typeof value === "undefined")
) {
return;
}
let msg;
if (allowUndefined) {
msg = `Expected opts.${name} to be either a ${type}, or undefined.`;
} else {
msg = `Expected opts.${name} to be a ${type}.`;
}
throw makeError(msg, GENSYNC_OPTIONS_ERROR);
}
function makeError(msg, code) {
return Object.assign(new Error(msg), { code });
}
/**
* Given an options object, return a new generator that dispatches the
* correct handler based on sync or async execution.
*/
function newGenerator({ name, arity, sync, async, errback }) {
assertTypeof("string", "name", name, true /* allowUndefined */);
assertTypeof("number", "arity", arity, true /* allowUndefined */);
assertTypeof("function", "sync", sync);
assertTypeof("function", "async", async, true /* allowUndefined */);
assertTypeof("function", "errback", errback, true /* allowUndefined */);
if (async && errback) {
throw makeError(
"Expected one of either opts.async or opts.errback, but got _both_.",
GENSYNC_OPTIONS_ERROR
);
}
if (typeof name !== "string") {
let fnName;
if (errback && errback.name && errback.name !== "errback") {
fnName = errback.name;
}
if (async && async.name && async.name !== "async") {
fnName = async.name.replace(/Async$/, "");
}
if (sync && sync.name && sync.name !== "sync") {
fnName = sync.name.replace(/Sync$/, "");
}
if (typeof fnName === "string") {
name = fnName;
}
}
if (typeof arity !== "number") {
arity = sync.length;
}
return buildOperation({
name,
arity,
sync: function(args) {
return sync.apply(this, args);
},
async: function(args, resolve, reject) {
if (async) {
async.apply(this, args).then(resolve, reject);
} else if (errback) {
errback.call(this, ...args, (err, value) => {
if (err == null) resolve(value);
else reject(err);
});
} else {
resolve(sync.apply(this, args));
}
},
});
}
function wrapGenerator(genFn) {
return setFunctionMetadata(genFn.name, genFn.length, function(...args) {
return genFn.apply(this, args);
});
}
function buildOperation({ name, arity, sync, async }) {
return setFunctionMetadata(name, arity, function*(...args) {
const resume = yield GENSYNC_START;
if (!resume) {
// Break the tail call to avoid a bug in V8 v6.X with --harmony enabled.
const res = sync.call(this, args);
return res;
}
let result;
try {
async.call(
this,
args,
value => {
if (result) return;
result = { value };
resume();
},
err => {
if (result) return;
result = { err };
resume();
}
);
} catch (err) {
result = { err };
resume();
}
// Suspend until the callbacks run. Will resume synchronously if the
// callback was already called.
yield GENSYNC_SUSPEND;
if (result.hasOwnProperty("err")) {
throw result.err;
}
return result.value;
});
}
function evaluateSync(gen) {
let value;
while (!({ value } = gen.next()).done) {
assertStart(value, gen);
}
return value;
}
function evaluateAsync(gen, resolve, reject) {
(function step() {
try {
let value;
while (!({ value } = gen.next()).done) {
assertStart(value, gen);
// If this throws, it is considered to have broken the contract
// established for async handlers. If these handlers are called
// synchronously, it is also considered bad behavior.
let sync = true;
let didSyncResume = false;
const out = gen.next(() => {
if (sync) {
didSyncResume = true;
} else {
step();
}
});
sync = false;
assertSuspend(out, gen);
if (!didSyncResume) {
// Callback wasn't called synchronously, so break out of the loop
// and let it call 'step' later.
return;
}
}
return resolve(value);
} catch (err) {
return reject(err);
}
})();
}
function assertStart(value, gen) {
if (value === GENSYNC_START) return;
throwError(
gen,
makeError(
`Got unexpected yielded value in gensync generator: ${JSON.stringify(
value
)}. Did you perhaps mean to use 'yield*' instead of 'yield'?`,
GENSYNC_EXPECTED_START
)
);
}
function assertSuspend({ value, done }, gen) {
if (!done && value === GENSYNC_SUSPEND) return;
throwError(
gen,
makeError(
done
? "Unexpected generator completion. If you get this, it is probably a gensync bug."
: `Expected GENSYNC_SUSPEND, got ${JSON.stringify(
value
)}. If you get this, it is probably a gensync bug.`,
GENSYNC_EXPECTED_SUSPEND
)
);
}
function throwError(gen, err) {
// Call `.throw` so that users can step in a debugger to easily see which
// 'yield' passed an unexpected value. If the `.throw` call didn't throw
// back to the generator, we explicitly do it to stop the error
// from being swallowed by user code try/catches.
if (gen.throw) gen.throw(err);
throw err;
}
function isIterable(value) {
return (
!!value &&
(typeof value === "object" || typeof value === "function") &&
!value[Symbol.iterator]
);
}
function setFunctionMetadata(name, arity, fn) {
if (typeof name === "string") {
// This should always work on the supported Node versions, but for the
// sake of users that are compiling to older versions, we check for
// configurability so we don't throw.
const nameDesc = Object.getOwnPropertyDescriptor(fn, "name");
if (!nameDesc || nameDesc.configurable) {
Object.defineProperty(
fn,
"name",
Object.assign(nameDesc || {}, {
configurable: true,
value: name,
})
);
}
}
if (typeof arity === "number") {
const lengthDesc = Object.getOwnPropertyDescriptor(fn, "length");
if (!lengthDesc || lengthDesc.configurable) {
Object.defineProperty(
fn,
"length",
Object.assign(lengthDesc || {}, {
configurable: true,
value: arity,
})
);
}
}
return fn;
}