npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@beezwax/fmbond

v1.3.1

Published

A bridge for sending/receiving data between FileMaker and the web viewer

Downloads

22

Readme

FMBond

Table of Contents


Introduction

FMBondJS is part of the FMBond toolset. It manages interactions between FileMaker scripts and FileMaker web viewers.

Features

  • Get FileMaker script results as JavaScript Promises.
  • Perform JavaScript functions from FileMaker and return the results to FileMaker as part of the regular script flow.
  • Safely wait for the availability of the FileMaker injected class before attempting to perform scripts.
  • Extend through a built-in plugin registration system.

FMBondJS is also used as the function runner for the FMBondServer web service

Installation

  1. Install FMBondJS
npm i @beezwax/fmbond
  1. Download the following FileMaker file, and copy the FMBondRelay script into the target FileMaker file.
curl -O https://github.com/beezwax/fmbond-relay-script/raw/main/fmbond-relay-script.fmp12

Requirements

  • FileMaker 19.3 or higher.
  • All FileMaker web viewer objects used with FMBondJS must be named in the FileMaker layout inspector.
  • The option 'Allow JavaScript to perform FileMaker scripts' must be checked in all web viewers used with FMBondJS.

Usage

Performing FileMaker Scripts from JavaScript

FMBond.PerformScript(scriptName, scriptParameter [, options])

FMBond.PerformScript("add two numbers", { firstNum: 1, secondNum: 2 })
    .then((result) => console.log(result));

FMBond.PerformScript("Get User Data", "user-123", { timeout: 3000 })
    .then((data) => console.log(data.firstName))
    .catch((e) => console.log('request took too long', e));

The options object is optional and can contain any of the following (defaults shown):

{
    webViewerName: "",         // The name of the web viewer hosting the web code.
    timeout: null,             // Number of milliseconds to wait before a promise is rejected.
    callType: 0                // The FileMaker 'call type'.
    relayScript: "FMBondRelay" // The relay script as it is named in the FileMaker solution.
    ignoreResult: false        // When true, promise resolves immediately - does not wait for FileMaker script.
}

The callType can be any of the following values (when not provided it is "continue" by default). See the Claris documentation for more details

"continue"  (or 0, "0")
"halt"      (or 1, "1")
"exit"      (or 2, "2")
"resume"    (or 3, "3")
"pause"     (or 4, "4")
"interrupt" (or 5, "5")

The callType can alternatively be provided as the third parameter to PerformScript.

    FMBond.PerformScript("Get Data", "", { callType: "interrupt" });
    // is equal to
    FMBond.PerformScript("Get Data", "", "interrupt" );

FMBond.SetWebViewerName(webViewerName) | FMBond.GetWebViewerName()

The Web Viewer name can be globally adjusted. The provided FMBondRelay script does not require this, however when using a custom relay script usng the spec, the web viewer name may need to set in JS code.

    FMBond.GetWebViewerName(); // "" (default)
    FMBond.SetWebViewerName("myWebViewer");
    FMBond.GetWebViewerName(); // "myWebViewer"

FMBond.SetRelayScriptName(relayScriptName) | FMBond.GetRelayScriptName()

The Relay Script name can be globally adjusted. This is required if the default name (FMBondRelay) is not used.

FMBond.GetRelayScriptName(); // "FMBondRelay" (default)
FMBond.SetRelayScriptName("My Relay Script");
FMBond.GetRelayScriptName(); // "My Relay Script"

FMBond.SetWebViewerNameFromFM()

Determines the name of the web viewer that FMBond is running in and stores it. This is useful for ensuring that subsequent FMBond.PerformScript calls do not invoke potentially expensive searches for the initiating web viewer.

Returns a promise

FMBond.GetWebViewerName(); // ""
FMBond.SetWebViewerNameFromFM()
    .then((result) => {
        console.log(result) // "myWV"
        console.log(FMBond.GetWebViewerName()) // "myWV"
    });

FMBond.SyncConfig()

By defining a JSON blob in the Web Address portion of the Web Viewer:

  • SyncConfig returns the Web Viewer JSON configuration as a promise result.
  • SetWebViewerConfigFromFM calls FileMaker and updates the configuration stored in FMBond.
  • SetWebViewerConfig(webViewerConfig) allows manual overwrite of the configuration stored in FMBond.
  • GetConfig returns the current configuration stored in FMBond.
// For example:
// • A Web Viewer is in the context of the PERSON table.
// • The PERSON::NAME field is "John Smith".
// • This Web Viewer's Web Address is set to JSONSetElement( "{}" ; "NAME" ; PERSON::NAME ; JSONString )

FMBond.GetConfig() // "{}"
FMBond.SetConfig({"NAME": "Kevin Paddlesmith"});
FMBond.GetConfig() // { "NAME": "Kevin Paddlesmith" }
FMBond.SyncConfig().then((config) => {
    console.log(config.NAME) // "John Smith"
});

FMBond.RegisterScript(pluginOptions)

It possible to extend FMBond by registering custom FileMaker scripts, which can then be can be called as methods. This allows the FMBondRelay script to be bypassed and may make it easier to implement custom behavior.

  1. Create a script in FileMaker.
  2. Perform FMBond.RegisterScript giving it the appropriate pluginOptions.

pluginOptions

  • exec: the method that becomes available to use on the FMBond class.
  • scriptName: the FileMaker script that will be run when the method defined in exec is called.
  • throwIf: (optional) callback function that takes the result of the script defined in scriptName as a parameter. If the function returns true an error will be thrown.
// define the script
FMBond.RegisterScript({
    exec: "executeDataApi",
    scriptName: "Execute Data Api",
    throwIf: (scriptResult) => {
        return scriptResult.messages[0].code !== "0" ;
    },
});


// Performing the script
const myQuery = {
    layouts: "FAKE_DATA",
    query: [{
        SOME_DATA: "==definitely data here",
    }],
};
FMBond.executeDataApi(myQuery)
    .then((result) => {
        console.log('my data', result);
    })
    .catch((e) => {
        console.log('query failed', e.toString());
    });


// The second parameter can also take advantage of FMBond options
FMBond.executeDataApi(myQuery, { timeout: 3000, callType: "interrupt" })
    .then((result) => {
        console.log('my data', result);
    })
    .catch((e) => {
        console.log('query failed', e.toString());
    });

Promise rejection and Error Handling

The promises settled by the FMBondRelay script will only reject when the specified FileMaker script is missing.

Otherwise, the result of the script's Exit Script[] step will be returned as the result of resolved promise and not a rejected promise. Because there is no standard way to indicate that a FileMaker script resulted in an error, the result of the promise will need to be inspected and an error thrown if required.

Note that when registering a plugin, the throwIf parameter can be used set the result state(s) that should throw errors.


Performing JavaScript functions from FileMaker

A web viewer that contains the FMBond class can return the result of a JavaScript function performed by FileMaker's Perform Javascript in Web Viewer script step. This allows the following FileMaker scripting pattern:

Perform JavaScript in Web Viewer [ ... ]
Set Variable[ $javaScriptResult; Get ( ScriptResult ) ]

That is, results of functions called using Perform Javascript in Web Viewer can be captured inline with minimal impact on the normal FileMaker script flow.

To utilize this feature configure the Perform Javascript in Web Viewer script step as follows:

  • Function Name: FMBond
  • First parameter either
    • a function in the global (window) JavaScript context of the web viewer OR
    • a JavaScript function (arrow or classic) defined as a string
  • Subsequent parameters will be passed into the function. To treat a JavaScript parameter as a callback function, prefix it with the 'ƒ' symbol (⌥ + f on macs).

Results are always obtained via Get ( ScriptResult ), nested in the response.result key. The response.result prop will be appropriately formatted (eg: as a number for numbers, string for strings, object for objects, etc...).

Example 1 Calling a function AddTwoNumbers that is accessible via window.AddTwoNumbers in the web viewer.

Perform JavaScript in Web Viewer [
    Object Name: "MyWebViewer" ;
    Function Name: "FMBond" ;
    Parameters: "AddTwoNumbers", 3, 5 
]

Set Variable [
    $_new_number ;
    Value: JSONGetElement ( Get ( ScriptResult ) ; "response.result" )
]
// $_new_number = 8

Example 2 Calling a FileMaker-defined function (define and run JavaScript on the fly in FileMaker)

Set Variable [
    $_add_two_numbers_func ;
    Value: "(a, b) => a + b"
]

Perform JavaScript in Web Viewer [
    Object Name: "MyWebViewer" ;
    Function Name: "FMBond" ;
    Parameters: $_add_two_numbers_func, 3, 5
]

Set Variable [
    $_new_number ;
    Value: JSONGetElement ( Get ( ScriptResult ) ; "response.result" )
]
// $_new_number = 8

Example 3 Support for Callbacks (remember to prefix with an 'ƒ')

Set Variable [
    $_add_number_with_callback ;
    Value: "function (myCallbackForC, a, b, c) { return a + b + myCallbackForC(c); }"
]

Set Variable [
    $_times_two ;
    Value: "ƒ(value) => value * 2"
]

Perform JavaScript in Web Viewer [
    Object Name: "MyWebViewer" ;
    Function Name: "FMBond" ;
    Parameters: $_add_two_numbers_func, $_times_two, 3, 5, 50
]

Set Variable [
    $_new_number ;
    Value: JSONGetElement ( Get ( ScriptResult ) ; "response.result" )
]
// $_new_number = 108

Get ( ScriptResult ) response

{
	"messages" :
	[
		{
			"code" : "0",
			"message" : "OK"
		}
	],
	"response" :
	{
		"result" : 108
	}
}

Errors are captured and returned for the following scenarios:

  • function does not exist in JavaScript.
  • function defined in FileMaker has invalid syntax (for example, a missing parenthesis: "(a, b => a + b").
  • function executed in JavaScript throws an error.
  • FMBond does not exist in the web viewer (in this case, the PerformJavascript step itself will surface an error).
{
	"messages" :
	[
		{
			"code" : "5",
			"message" : "The function 'MyGlobalFunc' is missing from the global scope, or is not a valid function definition"
		}
	],
	"response" : {}
}

Contributors

Brendan Pierce, Alec Gregory, Brandon Montoya, Max Petrusenko, and valuable contributions from members of the Beezwax team