jwillinghalpern / fm-gofer Goto Github PK
View Code? Open in Web Editor NEWAn easy fetch-like promise library for FileMaker WebViewer apps and widgets.
License: ISC License
An easy fetch-like promise library for FileMaker WebViewer apps and widgets.
License: ISC License
Maybe set default to fmRunCallback.
This should be exposed globally so that FM scripts can call it directly with Perform JavaScript In Webviewer.
I'm seeing this in Problems
in VSCode:
File '/Volumes/Macintosh HD/Users/JoshStorage/Downloads/wv-codes/node_modules/fm-mock/dist/fm-mock.d.ts' is not a module.
A polyfill will add a lot of bloat so maybe we should do multiple builds. One without the polyfill and one with.
For users who have a build step in their project, they might already have a polyfill being applied, so even if those users are building for IE11, they could use the slimmer modern build of this project.
Dan pointed me to this https://github.com/stefanpenner/es6-promise
Think more about this. The main reason I added this was so it would be obvious when you misconfigure your callback. For example if you pass in a non-existent callback id, then the promise
variable will return undefined. Then promise.timeoutID
will throw an error because you can't get a property of undefined.
We should add an explicit error message for when typeof promise === 'undefined'
.
Then decide if we should actually log an error and alert(), or if we should let the exception bubble up.
dan said in slack:
I was working on the FM script that's called by the WV JS and I was wondering if the "data" key in the script parameter should be "parameter", to match the name used when calling FileMaker.PerformScript ( script, parameter ); . It might help tie together the fact that it is the parameter the JS code sent to FM.
This behavior is useful when you're developing but it can be disruptive in production.
For example, if you webviewer app calls a FM script onload, if you're flipping through records quickly, the FM script called by the WV on one record could theoretically try to callback to a webviewer instance on a different record. This will result in frequent error alerts saying the supplied promiseID couldn't be found.
Maybe just console.log instead.
Consider making this toggleable
"The FM script call timed out"
Consider mentioning the optional timeout
param directly in this message so developers can try increasing that value for slow FM scripts.
mockScript should be typed more like:
export declare function mockScript(scriptName: string, functionToCall: (param: string) => void): void;
1000 is probably cutting it too close for some fm data fetch scripts.
If FileMaker is never found, then the promise will never resolve either.
Line 120 in 5081a97
Say you wish to send {"message": "hello"}
. Currently that gets changed to {"message": "hello", "callbackID": 1}
.
But maybe it should get changed to this instead:
{
"callbackID": 1,
"data": {"message": "hello"}
}
something like:
type GoferCallback = (promiseID: string, result?: string, isError?: string) => void;
declare global {
interface Window {
[callbackName: string]: GoferCallback;
...
Fallback callback that FM can call in the event that FMGofer sends malformed JSON, or when FM fails to parse the JSON due to developer error. This would allow the WV to handle this without relying solely on the timeout feature.
I keep seeing mention of named vs default exports as they relate to webpack/rollup tree shaking. If memory serves treeshaking requires named exports by default. Anyway, just something to check.
It would be nice to be able to cancel a request made to filemaker, if for example a React useEffect
hook initiates a request but the component is then unmounted. We could use the abort controller to tell FMGofer to stop waiting for a response and prevent it from logging the timeout error in the console. I.e. cancel the promise.
Reference article from Fabio: https://spencerfeng.medium.com/create-an-abortable-api-using-abortcontroller-and-abortsignal-d774bed40701
Line 66 in 65a9e59
Parameters are one or more optional text parameters to pass to the JavaScript function.
โ https://help.claris.com/en/pro-help/content/perform-javascript-in-web-viewer.html
Currently, you can't pass a 3rd parameter otherwise it'll fail.
right now the setInterval never ends. I copied this code from FMOnReady (Stephan Casas), and I think we should modify it a little to timeout eventually and clearInterval
It might be better to name it something like fm-gofer.umd.js and fm-gofer.cjs.js instead of "main".
This wouldn't matter in an nom context where you use the module name, but for using the umd in a script tag src attribute, a descriptive name would be preferable.
Look into some kind of test coverage analyzer tool. "Coveralls"?
Change all code that references the old name.
maybe instead of the type telling the fn whether to parse, as I mused here #32, it could instead take a parse
param (as part of an options
object) that tells FMGofer to auto-parse.
That way, when using fm-gofer and fm-mock together, you can declare the parameter passed into the mock FM script and it makes writing mocks easier, with more autocomplete.
One thing... I'm not sure if you can declare a type for a stringified JSON object and validate the various keys.
Reading this thread, this might be a bit beyond my current grasp of Typescript.
Ideally we'd remain backward compatibility by overloading the call signature. something like:
/**
* @enum {number}
* @member Default - Default is same as Continue.
* @member Continue - After a currently running FileMaker script has completed, queued FileMaker scripts are run in order. If FileMaker script execution is canceled, the queue is cleared. (This is the behavior if option is not specified. This is also the default behavior for FileMaker.PerformScript().)
* @member Halt - Execution of a currently running FileMaker script is halted, and all other pending scripts (queued or in the call stack) are canceled. Then script is run.
* @member Exit - A currently paused FileMaker script is exited. If the current FileMaker script was called by another FileMaker script, control returns to the calling FileMaker script until no more scripts remain in the call stack. Then script is run.
* @member Resume - A paused FileMaker script is resumed. After the resumed script is completed, script is run.
* @member Pause - A paused FileMaker script remains paused. If the paused script is resumed and completed, then script is run.
* @member Suspend - and Resume A currently running FileMaker script is suspended and script is run. When script is completed, the suspended script resumes with the next script step. A paused script remains paused while script is run.
*/
export enum ScriptOption {
Default = 0,
Continue = 0,
Halt = 1,
Exit = 2,
Resume = 3,
Pause = 4,
SuspendAndResume = 5,
}
ScriptOption.Halt
type ScriptOptionString = '0' | '1' | '2' | '3' | '4' | '5';
interface FMGoferType {
PerformScript (script: string, options: {
parameter?: any,
option?: ScriptOption | ScriptOptionString,
timeoutMs?: number,
timeoutMessage?: string,
})
}
// extend window with FMGofer
declare global {
interface Window {
FMGofer: FMGoferType
}
}
window.FMGofer.PerformScript('hello world', {
option: ScriptOption.Halt,
parameter: 'hello world',
timeoutMs: 1000,
timeoutMessage: 'oh no!',
})
current (ok):
interface Window {
FileMaker: {
PerformScript: Function;
PerformScriptWithOption: Function;
};
proposed (better):
interface Window {
FileMaker: {
PerformScript: (scriptName: string, parameter?: string) => void;
PerformScriptWithOption: (scriptName: string, parameter?: string, timeoutInSeconds?: number | string) => void;
};
FMGofer.PerformScript<T>
I'm not sure if this is possible since types are compiled away, but maybe the type could also tell FMGofer whether it should try to parse the response automatically or not. I don't think that's possible, just spitballing. Even if not, I still like the idea.
Something like this should appear in fm-gofer.d.ts
export interface GoferParam {
parameter?: any;
callbackName: string;
promiseID: string;
}
The point is so that in projects that use fm-gofer and fm-mock together, you can type the params passed to your mock functions. If you're not using fm-mock, it doesn't matter because no JS functions will receive the input of FMGofer, only the FM script called will.
This is more for me than anyone else.
failed
would be a boolean:
Perform JavaScript In Web Viewer [ "fmCallback" ; $callbackID ; False ; $returnData ]
to resolve the promise.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.