@iann29/rastro 0.10.9 → 0.11.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/README.md +8 -0
- package/agent/integration.md +45 -0
- package/agent/manifest.json +4 -4
- package/dist/client/federation.d.ts +82 -9
- package/dist/client/federation.d.ts.map +1 -1
- package/dist/client/federation.js +40 -2
- package/dist/client/federation.js.map +1 -1
- package/dist/client/index.d.ts +464 -8
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +259 -7
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +10 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +273 -21
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/server.d.ts +2 -0
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/constants.d.ts +31 -0
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +31 -0
- package/dist/component/constants.js.map +1 -1
- package/dist/component/convex.config.d.ts +2 -0
- package/dist/component/convex.config.js +7 -0
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/errors.d.ts +1 -1
- package/dist/component/errors.d.ts.map +1 -1
- package/dist/component/errors.js.map +1 -1
- package/dist/component/http.d.ts.map +1 -1
- package/dist/component/http.js +64 -0
- package/dist/component/http.js.map +1 -1
- package/dist/component/leadAdsValidators.d.ts +1092 -0
- package/dist/component/leadAdsValidators.d.ts.map +1 -0
- package/dist/component/leadAdsValidators.js +304 -0
- package/dist/component/leadAdsValidators.js.map +1 -0
- package/dist/component/leadFormRules.d.ts +60 -0
- package/dist/component/leadFormRules.d.ts.map +1 -0
- package/dist/component/leadFormRules.js +140 -0
- package/dist/component/leadFormRules.js.map +1 -0
- package/dist/component/leadFormStore.d.ts +16 -0
- package/dist/component/leadFormStore.d.ts.map +1 -0
- package/dist/component/leadFormStore.js +92 -0
- package/dist/component/leadFormStore.js.map +1 -0
- package/dist/component/leadgenToken.d.ts +56 -0
- package/dist/component/leadgenToken.d.ts.map +1 -0
- package/dist/component/leadgenToken.js +262 -0
- package/dist/component/leadgenToken.js.map +1 -0
- package/dist/component/leads.d.ts +76 -7
- package/dist/component/leads.d.ts.map +1 -1
- package/dist/component/leads.js +112 -78
- package/dist/component/leads.js.map +1 -1
- package/dist/component/meta.d.ts.map +1 -1
- package/dist/component/meta.js +21 -1
- package/dist/component/meta.js.map +1 -1
- package/dist/component/metaFake.d.ts +44 -0
- package/dist/component/metaFake.d.ts.map +1 -1
- package/dist/component/metaFake.js +400 -1
- package/dist/component/metaFake.js.map +1 -1
- package/dist/component/metaGraph.d.ts +91 -0
- package/dist/component/metaGraph.d.ts.map +1 -1
- package/dist/component/metaGraph.js +217 -0
- package/dist/component/metaGraph.js.map +1 -1
- package/dist/component/metaLeads.d.ts +681 -0
- package/dist/component/metaLeads.d.ts.map +1 -0
- package/dist/component/metaLeads.js +2634 -0
- package/dist/component/metaLeads.js.map +1 -0
- package/dist/component/schema.d.ts +414 -5
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +169 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/validators.d.ts +235 -11
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +14 -1
- package/dist/component/validators.js.map +1 -1
- package/dist/tracker/generated.d.ts +1 -1
- package/dist/tracker/generated.js +1 -1
- package/dist/ui/campaigns/CampaignsView.d.ts +5 -1
- package/dist/ui/campaigns/CampaignsView.d.ts.map +1 -1
- package/dist/ui/campaigns/CampaignsView.js.map +1 -1
- package/dist/ui/campaigns/Drawer.d.ts.map +1 -1
- package/dist/ui/campaigns/Drawer.js +8 -26
- package/dist/ui/campaigns/Drawer.js.map +1 -1
- package/dist/ui/campaigns/labels.d.ts +29 -1
- package/dist/ui/campaigns/labels.d.ts.map +1 -1
- package/dist/ui/campaigns/labels.js +77 -2
- package/dist/ui/campaigns/labels.js.map +1 -1
- package/dist/ui/campaigns/model.js +2 -2
- package/dist/ui/campaigns/model.js.map +1 -1
- package/dist/ui/forms/FirstContact.d.ts +19 -0
- package/dist/ui/forms/FirstContact.d.ts.map +1 -0
- package/dist/ui/forms/FirstContact.js +81 -0
- package/dist/ui/forms/FirstContact.js.map +1 -0
- package/dist/ui/forms/FormLead.d.ts +28 -0
- package/dist/ui/forms/FormLead.d.ts.map +1 -0
- package/dist/ui/forms/FormLead.js +199 -0
- package/dist/ui/forms/FormLead.js.map +1 -0
- package/dist/ui/forms/FormRulesDrawer.d.ts +49 -0
- package/dist/ui/forms/FormRulesDrawer.d.ts.map +1 -0
- package/dist/ui/forms/FormRulesDrawer.js +149 -0
- package/dist/ui/forms/FormRulesDrawer.js.map +1 -0
- package/dist/ui/forms/FormsView.d.ts +10 -0
- package/dist/ui/forms/FormsView.d.ts.map +1 -0
- package/dist/ui/forms/FormsView.js +215 -0
- package/dist/ui/forms/FormsView.js.map +1 -0
- package/dist/ui/forms/Icons.d.ts +46 -0
- package/dist/ui/forms/Icons.d.ts.map +1 -0
- package/dist/ui/forms/Icons.js +45 -0
- package/dist/ui/forms/Icons.js.map +1 -0
- package/dist/ui/forms/RuleRow.d.ts +37 -0
- package/dist/ui/forms/RuleRow.d.ts.map +1 -0
- package/dist/ui/forms/RuleRow.js +80 -0
- package/dist/ui/forms/RuleRow.js.map +1 -0
- package/dist/ui/forms/WhatsAppButtonGuide.d.ts +33 -0
- package/dist/ui/forms/WhatsAppButtonGuide.d.ts.map +1 -0
- package/dist/ui/forms/WhatsAppButtonGuide.js +90 -0
- package/dist/ui/forms/WhatsAppButtonGuide.js.map +1 -0
- package/dist/ui/forms/index.d.ts +11 -0
- package/dist/ui/forms/index.d.ts.map +1 -0
- package/dist/ui/forms/index.js +7 -0
- package/dist/ui/forms/index.js.map +1 -0
- package/dist/ui/forms/journey.d.ts +19 -0
- package/dist/ui/forms/journey.d.ts.map +1 -0
- package/dist/ui/forms/journey.js +54 -0
- package/dist/ui/forms/journey.js.map +1 -0
- package/dist/ui/forms/model.d.ts +239 -0
- package/dist/ui/forms/model.d.ts.map +1 -0
- package/dist/ui/forms/model.js +556 -0
- package/dist/ui/forms/model.js.map +1 -0
- package/dist/ui/forms/sample.d.ts +36 -0
- package/dist/ui/forms/sample.d.ts.map +1 -0
- package/dist/ui/forms/sample.js +444 -0
- package/dist/ui/forms/sample.js.map +1 -0
- package/dist/ui/forms/types.d.ts +454 -0
- package/dist/ui/forms/types.d.ts.map +1 -0
- package/dist/ui/forms/types.js +2 -0
- package/dist/ui/forms/types.js.map +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +4 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/integrations/Overlay.d.ts +3 -1
- package/dist/ui/integrations/Overlay.d.ts.map +1 -1
- package/dist/ui/integrations/Overlay.js +2 -2
- package/dist/ui/integrations/Overlay.js.map +1 -1
- package/dist/ui/portfolio/PortfolioView.d.ts +4 -1
- package/dist/ui/portfolio/PortfolioView.d.ts.map +1 -1
- package/dist/ui/portfolio/PortfolioView.js.map +1 -1
- package/dist/ui/sample.d.ts +3 -1
- package/dist/ui/sample.d.ts.map +1 -1
- package/dist/ui/sample.js +2 -0
- package/dist/ui/sample.js.map +1 -1
- package/dist/ui/seed.d.ts +1 -1
- package/dist/ui/ui.css +2301 -0
- package/docs/federation.md +19 -0
- package/docs/meta-ads.md +713 -7
- package/docs/upgrading.md +70 -0
- package/llms.txt +1 -0
- package/package.json +1 -1
- package/src/component/_generated/api.ts +10 -0
- package/src/component/_generated/component.ts +289 -20
- package/src/component/_generated/server.ts +2 -0
- package/src/component/constants.ts +33 -0
- package/src/component/convex.config.ts +7 -0
- package/src/component/errors.ts +3 -1
- package/src/component/http.ts +75 -0
- package/src/component/leadAdsValidators.ts +365 -0
- package/src/component/leadFormRules.ts +202 -0
- package/src/component/leadFormStore.ts +129 -0
- package/src/component/leadgenToken.ts +348 -0
- package/src/component/leads.ts +136 -84
- package/src/component/meta.ts +21 -1
- package/src/component/metaFake.ts +485 -1
- package/src/component/metaGraph.ts +327 -0
- package/src/component/metaLeads.ts +3101 -0
- package/src/component/schema.ts +187 -1
- package/src/component/validators.ts +17 -1
- package/src/tracker/generated.ts +1 -1
package/src/component/schema.ts
CHANGED
|
@@ -28,6 +28,13 @@ import {
|
|
|
28
28
|
reportRollupQueueFields,
|
|
29
29
|
rollupFoldStateFields,
|
|
30
30
|
} from "./rollupStore.js";
|
|
31
|
+
import {
|
|
32
|
+
firstContactValidator,
|
|
33
|
+
formChoiceAnswerValidator,
|
|
34
|
+
formLeadDecisionValidator,
|
|
35
|
+
formRuleValidator,
|
|
36
|
+
metaFormQuestionValidator,
|
|
37
|
+
} from "./leadAdsValidators.js";
|
|
31
38
|
|
|
32
39
|
export default defineSchema({
|
|
33
40
|
sites: defineTable(siteFieldsValidator)
|
|
@@ -424,7 +431,8 @@ export default defineSchema({
|
|
|
424
431
|
leadDailyRollups: defineTable({
|
|
425
432
|
siteId: v.id("sites"),
|
|
426
433
|
dayStart: v.number(),
|
|
427
|
-
|
|
434
|
+
// `form` (since 0.11.0): a Meta instant form's leads, keyed by form id.
|
|
435
|
+
dimension: v.union(v.literal("origin"), v.literal("ad"), v.literal("form")),
|
|
428
436
|
key: v.string(),
|
|
429
437
|
leads: v.number(),
|
|
430
438
|
qualified: v.number(),
|
|
@@ -765,4 +773,182 @@ export default defineSchema({
|
|
|
765
773
|
Lead: v.number(),
|
|
766
774
|
Schedule: v.number(),
|
|
767
775
|
}).index("by_siteId_and_dayStart_and_shard", ["siteId", "dayStart", "shard"]),
|
|
776
|
+
|
|
777
|
+
// Lead Ads (metaLeads.ts, since 0.11.0). No table here ever holds a lead's
|
|
778
|
+
// name, phone, e-mail or free answer: those go from Meta to the host's
|
|
779
|
+
// handler in memory.
|
|
780
|
+
|
|
781
|
+
// A Facebook Page an owner's connection lists, with the Page's own token
|
|
782
|
+
// sealed with RASTRO_SECRETS_KEY (one row per connection and Page: two
|
|
783
|
+
// owners may list the same Page). No query returns the cipher.
|
|
784
|
+
metaPages: defineTable({
|
|
785
|
+
ownerKey: v.string(),
|
|
786
|
+
connectionId: v.id("metaConnections"),
|
|
787
|
+
pageId: v.string(),
|
|
788
|
+
name: v.string(),
|
|
789
|
+
tokenCipher: v.string(),
|
|
790
|
+
tokenIv: v.string(),
|
|
791
|
+
/** The Page tasks Meta granted the login: `ADVERTISE`, `MANAGE`… */
|
|
792
|
+
tasks: v.array(v.string()),
|
|
793
|
+
/** The login was granted `leads_retrieval` for this Page. */
|
|
794
|
+
leadsAllowed: v.boolean(),
|
|
795
|
+
/** False once a new listing left the Page out; kept while linked. */
|
|
796
|
+
listed: v.boolean(),
|
|
797
|
+
/** When Meta refused the Page's token; a new listing clears it. */
|
|
798
|
+
invalidSince: v.optional(v.number()),
|
|
799
|
+
createdAt: v.number(),
|
|
800
|
+
updatedAt: v.number(),
|
|
801
|
+
})
|
|
802
|
+
.index("by_connectionId_and_pageId", ["connectionId", "pageId"])
|
|
803
|
+
.index("by_pageId", ["pageId"]),
|
|
804
|
+
|
|
805
|
+
// A Page feeding a site's leads: subscribed to Meta's `leadgen` webhook and
|
|
806
|
+
// reconciled by the chain in metaLeads.ts. One Page feeds one site.
|
|
807
|
+
sitePages: defineTable({
|
|
808
|
+
siteId: v.id("sites"),
|
|
809
|
+
pageId: v.string(),
|
|
810
|
+
name: v.string(),
|
|
811
|
+
/** The owner whose connection (and Page token) the link reads with. */
|
|
812
|
+
ownerKey: v.string(),
|
|
813
|
+
connectionId: v.id("metaConnections"),
|
|
814
|
+
/** When Meta confirmed the `leadgen` subscription. */
|
|
815
|
+
subscribedAt: v.optional(v.number()),
|
|
816
|
+
/**
|
|
817
|
+
* When the reconciliation last made sure the app is still subscribed to
|
|
818
|
+
* the Page: the subscription is the Page's and the app's, shared by every
|
|
819
|
+
* host, so another host unlinking the Page may have taken it off.
|
|
820
|
+
*/
|
|
821
|
+
subscriptionCheckedAt: v.optional(v.number()),
|
|
822
|
+
/** Leads created from here on are the link's (ms). */
|
|
823
|
+
reconcileFrom: v.number(),
|
|
824
|
+
nextReconcileAt: v.number(),
|
|
825
|
+
/** The run holding the link, as in the spend sync. */
|
|
826
|
+
runId: v.optional(v.string()),
|
|
827
|
+
lastReconcileAt: v.optional(v.number()),
|
|
828
|
+
lastLeadAt: v.optional(v.number()),
|
|
829
|
+
failures: v.optional(v.number()),
|
|
830
|
+
lastError: v.optional(v.string()),
|
|
831
|
+
createdAt: v.number(),
|
|
832
|
+
updatedAt: v.number(),
|
|
833
|
+
})
|
|
834
|
+
.index("by_siteId", ["siteId"])
|
|
835
|
+
.index("by_pageId", ["pageId"])
|
|
836
|
+
.index("by_connectionId", ["connectionId"])
|
|
837
|
+
.index("by_nextReconcileAt", ["nextReconcileAt"]),
|
|
838
|
+
|
|
839
|
+
// A Page's instant forms as Meta lists them.
|
|
840
|
+
metaForms: defineTable({
|
|
841
|
+
pageId: v.string(),
|
|
842
|
+
formId: v.string(),
|
|
843
|
+
name: v.string(),
|
|
844
|
+
status: v.string(),
|
|
845
|
+
questions: v.array(metaFormQuestionValidator),
|
|
846
|
+
/** The end screen's WhatsApp button; absent when Meta does not say. */
|
|
847
|
+
whatsappButton: v.optional(v.boolean()),
|
|
848
|
+
createdTime: v.optional(v.number()),
|
|
849
|
+
syncedAt: v.number(),
|
|
850
|
+
/**
|
|
851
|
+
* How far the reconciliation read this form's leads (Meta's seconds),
|
|
852
|
+
* for the link it read them for: a new link starts from its own time.
|
|
853
|
+
*/
|
|
854
|
+
cursor: v.optional(
|
|
855
|
+
v.object({ linkId: v.id("sitePages"), sec: v.number() }),
|
|
856
|
+
),
|
|
857
|
+
/** The last lead that came in from the form, for the site it fed. */
|
|
858
|
+
lastLead: v.optional(v.object({ siteId: v.id("sites"), at: v.number() })),
|
|
859
|
+
})
|
|
860
|
+
.index("by_pageId", ["pageId"])
|
|
861
|
+
.index("by_pageId_and_status", ["pageId", "status"])
|
|
862
|
+
.index("by_formId", ["formId"]),
|
|
863
|
+
|
|
864
|
+
// Where a site's form sends its leads. Editing affects the next leads only.
|
|
865
|
+
formRules: defineTable({
|
|
866
|
+
siteId: v.id("sites"),
|
|
867
|
+
formId: v.string(),
|
|
868
|
+
entryColumn: v.optional(v.string()),
|
|
869
|
+
rules: v.array(formRuleValidator),
|
|
870
|
+
/** Each rule's identity, for its monthly count (see leadFormRules.ts). */
|
|
871
|
+
signatures: v.array(v.string()),
|
|
872
|
+
firstContact: firstContactValidator,
|
|
873
|
+
whatsappButtonConfirmed: v.optional(v.boolean()),
|
|
874
|
+
/** The owner that saved them, when the host named one. */
|
|
875
|
+
setBy: v.optional(v.string()),
|
|
876
|
+
updatedAt: v.number(),
|
|
877
|
+
}).index("by_siteId_and_formId", ["siteId", "formId"]),
|
|
878
|
+
|
|
879
|
+
// One per ingested form lead: its origin, the choice answers and what the
|
|
880
|
+
// rules decided. `leadgenId` makes ingestion idempotent.
|
|
881
|
+
formLeads: defineTable({
|
|
882
|
+
siteId: v.id("sites"),
|
|
883
|
+
pageId: v.string(),
|
|
884
|
+
formId: v.string(),
|
|
885
|
+
leadgenId: v.string(),
|
|
886
|
+
leadId: v.id("leads"),
|
|
887
|
+
receivedAt: v.number(),
|
|
888
|
+
adId: v.optional(v.string()),
|
|
889
|
+
adsetId: v.optional(v.string()),
|
|
890
|
+
campaignId: v.optional(v.string()),
|
|
891
|
+
platform: v.optional(v.string()),
|
|
892
|
+
isOrganic: v.boolean(),
|
|
893
|
+
answers: v.array(formChoiceAnswerValidator),
|
|
894
|
+
decision: formLeadDecisionValidator,
|
|
895
|
+
rulePath: v.array(v.number()),
|
|
896
|
+
ruleIndex: v.optional(v.number()),
|
|
897
|
+
ruleSignature: v.optional(v.string()),
|
|
898
|
+
/** A discarded lead sent back to the funnel, and the reason it had. */
|
|
899
|
+
returned: v.optional(v.object({ at: v.number(), reason: v.string() })),
|
|
900
|
+
createdAt: v.number(),
|
|
901
|
+
})
|
|
902
|
+
.index("by_leadgenId", ["leadgenId"])
|
|
903
|
+
.index("by_leadId", ["leadId"])
|
|
904
|
+
.index("by_siteId_and_receivedAt", ["siteId", "receivedAt"])
|
|
905
|
+
.index("by_siteId_and_formId_and_receivedAt", [
|
|
906
|
+
"siteId",
|
|
907
|
+
"formId",
|
|
908
|
+
"receivedAt",
|
|
909
|
+
])
|
|
910
|
+
.index("by_siteId_and_formId_and_ruleSignature_and_receivedAt", [
|
|
911
|
+
"siteId",
|
|
912
|
+
"formId",
|
|
913
|
+
"ruleSignature",
|
|
914
|
+
"receivedAt",
|
|
915
|
+
]),
|
|
916
|
+
|
|
917
|
+
// A form lead the host removed (`leads.remove`): its leadgen id only, so
|
|
918
|
+
// no later read of the same lead (the webhook retried, the reconciliation
|
|
919
|
+
// reading the cursor's second, a new link's backfill) brings it back.
|
|
920
|
+
formLeadTombstones: defineTable({
|
|
921
|
+
leadgenId: v.string(),
|
|
922
|
+
removedAt: v.number(),
|
|
923
|
+
}).index("by_leadgenId", ["leadgenId"]),
|
|
924
|
+
|
|
925
|
+
// A form lead whose commit failed (the host's handler threw): its ids, how
|
|
926
|
+
// many times and the error's class or code, never its data. After
|
|
927
|
+
// `MAX_LEAD_ATTEMPTS` while later leads of the form come in, the
|
|
928
|
+
// reconciliation skips it (`skippedAt`) so they are not held behind it.
|
|
929
|
+
// Deleted when the lead comes in.
|
|
930
|
+
formLeadFailures: defineTable({
|
|
931
|
+
leadgenId: v.string(),
|
|
932
|
+
pageId: v.string(),
|
|
933
|
+
formId: v.string(),
|
|
934
|
+
attempts: v.number(),
|
|
935
|
+
lastCode: v.string(),
|
|
936
|
+
lastAt: v.number(),
|
|
937
|
+
skippedAt: v.optional(v.number()),
|
|
938
|
+
}).index("by_leadgenId", ["leadgenId"]),
|
|
939
|
+
|
|
940
|
+
// The host's form lead handler: a function handle the component calls with
|
|
941
|
+
// each lead (see `setFormLeadHandler`). One per deployment.
|
|
942
|
+
metaFormLeadHandler: defineTable({
|
|
943
|
+
key: v.literal("handler"),
|
|
944
|
+
handle: v.string(),
|
|
945
|
+
updatedAt: v.number(),
|
|
946
|
+
}).index("by_key", ["key"]),
|
|
947
|
+
|
|
948
|
+
// The single scheduler chain that reconciles every linked Page.
|
|
949
|
+
metaLeadsLoop: defineTable({
|
|
950
|
+
key: v.literal("loop"),
|
|
951
|
+
scheduledFor: v.number(),
|
|
952
|
+
jobId: v.id("_scheduled_functions"),
|
|
953
|
+
}).index("by_key", ["key"]),
|
|
768
954
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { v, type Infer } from "convex/values";
|
|
2
|
+
import { formLeadDetailValidator } from "./leadAdsValidators.js";
|
|
2
3
|
|
|
3
4
|
export const personAttributeValueValidator = v.union(
|
|
4
5
|
v.string(),
|
|
@@ -384,7 +385,14 @@ export const trackedLinkFieldsValidator = v.object({
|
|
|
384
385
|
* behind it. Today the channel is WhatsApp; the stage follows the host's
|
|
385
386
|
* pipeline as `lead` → `qualified` → `won`, or `lost`.
|
|
386
387
|
*/
|
|
387
|
-
|
|
388
|
+
/**
|
|
389
|
+
* Where the lead talks to the host: a WhatsApp conversation, or (since
|
|
390
|
+
* 0.11.0) a Meta instant form the lead filled in (`lead_form` origin).
|
|
391
|
+
*/
|
|
392
|
+
export const leadChannelValidator = v.union(
|
|
393
|
+
v.literal("whatsapp"),
|
|
394
|
+
v.literal("form"),
|
|
395
|
+
);
|
|
388
396
|
export const leadStageValidator = v.union(
|
|
389
397
|
v.literal("lead"),
|
|
390
398
|
v.literal("qualified"),
|
|
@@ -440,6 +448,8 @@ export const leadFieldsValidator = v.object({
|
|
|
440
448
|
/** The host's board column the lead is in now (see `setPipeline`). */
|
|
441
449
|
column: v.optional(v.string()),
|
|
442
450
|
columnAt: v.optional(v.number()),
|
|
451
|
+
/** Since 0.11.0: the Meta instant form the lead filled in (metaLeads.ts). */
|
|
452
|
+
form: v.optional(v.object({ formId: v.string(), pageId: v.string() })),
|
|
443
453
|
updatedAt: v.number(),
|
|
444
454
|
});
|
|
445
455
|
|
|
@@ -847,6 +857,12 @@ export const leadJourneyValidator = v.union(
|
|
|
847
857
|
}),
|
|
848
858
|
),
|
|
849
859
|
visitorId: v.union(v.string(), v.null()),
|
|
860
|
+
/**
|
|
861
|
+
* Since 0.11.0, on a Meta instant form's lead: its choice answers, where
|
|
862
|
+
* it came from and the path the form's rules took. Null when the lead
|
|
863
|
+
* has no ingestion record left.
|
|
864
|
+
*/
|
|
865
|
+
form: v.optional(v.union(formLeadDetailValidator, v.null())),
|
|
850
866
|
events: v.array(
|
|
851
867
|
v.object({
|
|
852
868
|
type: leadEventTypeValidator,
|
package/src/tracker/generated.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generated by scripts/build-tracker.mjs. Do not edit.
|
|
2
|
-
export const RASTRO_VERSION = "0.
|
|
2
|
+
export const RASTRO_VERSION = "0.11.0";
|
|
3
3
|
export const TRACKER_SOURCE = "(()=>{const t=document.currentScript,e=t?.dataset.site,i=t?.dataset.endpoint||t?.src&&new URL(\"events\",t.src).href;if(!e||!i)return;const n=()=>crypto.randomUUID?.()||Math.random()+\"\",r=new URLSearchParams(location.search),s=r.get(\"ref\")?.slice(0,64);let o;for(const t of[\"source\",\"medium\",\"campaign\",\"term\",\"content\"]){const e=r.get(\"utm_\"+t)?.slice(0,64);e&&((o??={})[\"utm_\"+t]=e)}const a=\"gclid gbraid wbraid msclkid ttclid twclid li_fat_id ScCid rdt_cid dclid epik srsltid mc_cid mc_eid _hsenc igsh igshid fbclid\".split(\" \").filter(t=>r.has(t)).slice(0,8);let c,d,l,h,f=t.dataset.visitor||\"\",p=Boolean(f);try{f||=localStorage._rv||=n()}catch{}try{d=sessionStorage,l=d._r,c=d._ri==f&&d._rt,h=s||d._a,h&&(d._a=h),o||=d._u&&JSON.parse(d._u),o&&(d._u=JSON.stringify(o))}catch{h=s}let v,g=0;const u=[];let m=document.referrer.split(\"/\",3).join(\"/\")||void 0;const _=t=>{const n=u.splice(0,50);if(!n.length)return;const r=()=>new Blob([JSON.stringify({siteId:e,events:n,sentAt:Date.now()})]);let s=r();for(;s.size>64e3&&n.length>1;)u.unshift(n.pop()),s=r();t&&navigator.sendBeacon(i,s)||fetch(i,{method:\"POST\",body:s,keepalive:1}).catch(()=>{}),u.length&&_(t)},y=(t,e,i)=>{const r=Date.now(),s=r-c;c=r,s<18e5||(l=n(),\"pageview\"!=t&&(S=\"\",w()));try{d._r=l,d._ri=f,d._rt=r}catch{}u.push({eventId:`${l}.${r.toString(36)}.${g}`,sessionId:l,visitorId:f||l,type:t,name:e,path:location.pathname.slice(0,256),referrer:m,timestamp:r,sequence:g++,affiliateSlug:h,...i}),clearTimeout(v),v=setTimeout(_,1200)};let S;const w=()=>{const t=location.pathname;t!=S&&(S=t,y(\"pageview\",void 0,{properties:o,clid:a.length?a:void 0}))};window.rastro=(e,i,r)=>{if(\"context\"==e)return{sessionId:l,visitorId:f||l,identified:p};if(\"identify\"==e||\"reset\"==e){if(\"identify\"==e&&(!i||i.length>128||!/^[A-Za-z0-9][A-Za-z0-9_.:-]*$/.test(i)))return;if(\"identify\"==e&&i==f)return;_();const r=\"reset\"==e||p;if(p=\"identify\"==e,f=\"identify\"==e?i:n(),t.dataset.visitor=\"identify\"==e?f:\"\",r){h=void 0,o=void 0,m=void 0,a.length=0;try{\"reset\"==e&&(localStorage._rv=f),d._a=\"\",d._u=\"\"}catch{}}c=0,g=0,S=\"\",w()}\"event\"==e&&y(\"custom\",`${i||\"event\"}`.slice(0,80),r&&JSON.stringify(r).length>2e4?void 0:{properties:r})},document.addEventListener(\"click\",t=>{const e=t.target?.closest(\"a,button,[data-rastro-event]\");if(!e)return;const i=e.dataset.rastroEvent,n=e.href,r=n&&new URL(n),s=/^https?:$/.test(r?.protocol),o=s&&r.origin!=location.origin;y(i?\"custom\":o?\"outbound\":\"click\",i,{target:(e.dataset.rastroLabel||e.innerText||e.tagName).slice(0,64),href:s?((o?r.origin:\"\")+r.pathname).slice(0,256):void 0})},1);for(const t of[\"pushState\",\"replaceState\"]){const e=history[t];history[t]=(...t)=>{e.apply(history,t),w()}}addEventListener(\"popstate\",w);let b=0;const I=()=>{y(\"heartbeat\"),_()},L=()=>{b&&(clearInterval(b),b=0,y(\"leave\"),_(1))},E=()=>{document.hidden?L():b||(I(),b=setInterval(I,2e4))};addEventListener(\"pagehide\",L),addEventListener(\"pageshow\",E),document.addEventListener(\"visibilitychange\",E),b=setInterval(I,2e4),w(),E()})();";
|
|
4
4
|
export const TRACKER_GZIP_BASE64 = "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";
|
|
5
5
|
export const TRACKER_RAW_BYTES = 2999;
|